pandasのインデックス参照で行・列を選択し取得

pandas.DataFrame, pandas.Seriesのインデックス(添字)[]を指定することで、行・列または要素の値を選択し取得することができます。 pandas.DataFrameの場合、[]の中に指定する値のタイプによって以下のようなデータが取得できます。

[列名] : 単独の列をpandas.Seriesとして取得 [列名のリスト] : 複数列をpandas.DataFrameとして取得 [行名・行番号のスライス] : 単独または複数行をpandas.DataFrameとして取得

pandas.Seriesの場合は以下のようになる。

[行名・行番号] : 単独の要素の値をそれぞれの型で取得 [行名・行番号のリスト] : 複数の要素の値をpandas.Seriesとして取得 [行名・行番号のスライス] : 単独または複数の要素の値をpandas.Seriesとして取得

pandas.DataFrameで要素の値を抽出したり、列をスライス、行を行名・行番号やそのリストで選択したい場合はat, iat, loc, ilocを使います。以下の記事を参照。

今回のサンプルコードでは以下のcsvデータをread_csvで読み込んで使用します。

sample_pandas_normal.csv

引数index_colで最初の列をindexとしています。

import pandas as pd

df = pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0)
print(df)
#          age state  point
# name                     
# Alice     24    NY     64
# Bob       42    CA     92
# Charlie   18    CA     70
# Dave      68    TX     70
# Ellen     24    CA     88
# Frank     30    NY     57

既存のDataFrameの列をset_index()でindexに指定することもできます。

pandas.DataFrameの列を取得

[]に列名(列ラベル)を指定すると、選択した列が抽出されpandas.Seriesとして取得できます。

print(df['age'])
print(type(df['age']))
# name
# Alice      24
# Bob        42
# Charlie    18
# Dave       68
# Ellen      24
# Frank      30
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>

attribute(属性)として.に続けて列名を指定することもできます。ただし、列名が既存のメソッド名などと被るとそちらが優先されるので注意が必要。

print(df.age)
print(type(df.age))
# name
# Alice      24
# Bob        42
# Charlie    18
# Dave       68
# Ellen      24
# Frank      30
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>

列名のリストを指定すると、選択した複数列が抽出されpandas.DataFrameとして取得できます。

print(df[['age', 'point']])
print(type(df[['age', 'point']]))
#          age  point
# name               
# Alice     24     64
# Bob       42     92
# Charlie   18     70
# Dave      68     70
# Ellen     24     88
# Frank     30     57
# <class 'pandas.core.frame.DataFrame'>

スライスの場合は空のpandas.DataFrameとなって使えない。スライスは行の指定だと見なされるため(後述)。

print(df['age':'point'])
# Empty DataFrame
# Columns: [age, state, point]
# Index: []

locを用いると列のスライスも可能。またilocを用いると列名(列ラベル)ではなく列番号で指定することもできます。詳細は以下の記事を参照。

print(df.loc[:, 'age':'point'])
print(type(df.loc[:, 'age':'point']))
#          age state  point
# name                     
# Alice     24    NY     64
# Bob       42    CA     92
# Charlie   18    CA     70
# Dave      68    TX     70
# Ellen     24    CA     88
# Frank     30    NY     57
# <class 'pandas.core.frame.DataFrame'>

print(df.iloc[:, [0, 2]])
print(type(df.iloc[:, [0, 2]]))
#          age  point
# name               
# Alice     24     64
# Bob       42     92
# Charlie   18     70
# Dave      68     70
# Ellen     24     88
# Frank     30     57
# <class 'pandas.core.frame.DataFrame'>

pandas.DataFrameの行を取得

[]にスライスを指定すると、該当範囲の複数行が抽出されpandas.DataFrameとして取得できます。

print(df[1:4])
print(type(df[1:4]))
#          age state  point
# name                     
# Bob       42    CA     92
# Charlie   18    CA     70
# Dave      68    TX     70
# <class 'pandas.core.frame.DataFrame'>

スライスなので、start:stop:stepのようにstepを指定することも可能。奇数行または偶数行を抽出して取得できます。

print(df[::2])
print(type(df[::2]))
#          age state  point
# name                     
# Alice     24    NY     64
# Charlie   18    CA     70
# Ellen     24    CA     88
# <class 'pandas.core.frame.DataFrame'>

print(df[1::2])
print(type(df[1::2]))
#        age state  point
# name                   
# Bob     42    CA     92
# Dave    68    TX     70
# Frank   30    NY     57
# <class 'pandas.core.frame.DataFrame'>

あくまでもスライスでないとダメで、行番号を単独で指定するとエラーとなります。

# print(df[1])
# KeyError

一行だけ選択される場合も、取得できるのはpandas.DataFrame。pandas.Seriesにはならない。

print(df[1:2])
print(type(df[1:2]))
#       age state  point
# name                  
# Bob    42    CA     92
# <class 'pandas.core.frame.DataFrame'>

行番号ではなく行名(行ラベル)でスライスを指定することもできます。行名(行ラベル)のスライスの場合はstopの行も選択される。

print(df['Bob':'Ellen'])
print(type(df['Bob':'Ellen']))
#          age state  point
# name                     
# Bob       42    CA     92
# Charlie   18    CA     70
# Dave      68    TX     70
# Ellen     24    CA     88
# <class 'pandas.core.frame.DataFrame'>

locやilocを用いると行に対して行名・行番号を単独で指定してpandas.Seriesとして取得したり、リストで複数行を選択したりできます。詳細は以下の記事を参照。

print(df.loc['Bob'])
print(type(df.loc['Bob']))
# age      42
# state    CA
# point    92
# Name: Bob, dtype: object
# <class 'pandas.core.series.Series'>

print(df.loc[['Bob', 'Ellen']])
print(type(df.loc[['Bob', 'Ellen']]))
#        age state  point
# name                   
# Bob     42    CA     92
# Ellen   24    CA     88
# <class 'pandas.core.frame.DataFrame'>

print(df.iloc[[1, 4]])
print(type(df.iloc[[1, 4]]))
#        age state  point
# name                   
# Bob     42    CA     92
# Ellen   24    CA     88
# <class 'pandas.core.frame.DataFrame'>

pandas.Seriesの値を取得

以下のpandas.Seriesを例とします。

s = df['age']
print(s)
# name
# Alice      24
# Bob        42
# Charlie    18
# Dave       68
# Ellen      24
# Frank      30
# Name: age, dtype: int64

行名・行番号の場合はその値、リストやスライスの場合は選択した複数の値をpandas.Seriesとして取得できます。リストやスライスの場合、一行だけが抽出されてもpandas.Series。 行名(行ラベル)のスライスの場合はstopの行も選択される。

print(s[3])
# 68

print(s[[1, 3]])
print(type(s[[1, 3]]))
# name
# Bob     42
# Dave    68
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>

print(s[1:3])
print(type(s[1:3]))
# name
# Bob        42
# Charlie    18
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>

print(s[[1]])
print(type(s[[1]]))
# name
# Bob    42
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>

print(s[1:2])
print(type(s[1:2]))
# name
# Bob    42
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>

print(s['Dave'])
# 68

print(s[['Bob', 'Dave']])
print(type(s[['Bob', 'Dave']]))
# name
# Bob     42
# Dave    68
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>

print(s['Bob':'Dave'])
print(type(s['Bob':'Dave']))
# name
# Bob        42
# Charlie    18
# Dave       68
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>

print(s[['Bob']])
print(type(s[['Bob']]))
# name
# Bob    42
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>

print(s['Bob':'Bob'])
print(type(s['Bob':'Bob']))
# name
# Bob    42
# Name: age, dtype: int64
# <class 'pandas.core.series.Series'>

行名が整数値の場合、行名・行番号の指定が曖昧になるため、例えば最終行を示す-1を指定するとエラーになる。行名と行番号を明確に区別して指定するにはpandas.Seriesに対してもat, iat, loc, ilocを使います。 以下の記事を参照。

行名が文字列であれば-1でもエラーは発生しない。

s_i = s.reset_index(drop=True)
print(s_i)
# 0    24
# 1    42
# 2    18
# 3    68
# 4    24
# 5    30
# Name: age, dtype: int64

# print(s_i[-1])
# KeyError

print(s_i.iat[-1])
# 30

print(s[-1])
# 30

pandas.DataFrameの要素の値を取得

pandas.DataFrameからpandas.Seriesを抽出し、さらにそのpandas.Seriesから値を選択して取得することで、pandas.DataFrameから要素の値を取得できます。

print(df['age']['Alice'])
# 24

print(df.age[0])
# 24

スライスやリストを組み合わせて任意の範囲を抽出することもできます。

print(df['Bob':'Dave'][['age', 'point']])
print(type(df['Bob':'Dave'][['age', 'point']]))
#          age  point
# name               
# Bob       42     92
# Charlie   18     70
# Dave      68     70
# <class 'pandas.core.frame.DataFrame'>

at, iat, loc, ilocを使うともっと柔軟に位置や範囲を選択して抽出することが可能。以下の記事を参照。

シェア

関連カテゴリー

Python pandas

pandas参考書『Python for Data Analysis, 2nd Edition』 pandasで要素、行、列に関数を適用するmap, applymap, apply pandas.DataFrameの行名・列名の変更 pandasで欠損値NaNが含まれているか判定、個数をカウント pandasで特定の条件を満たす要素数をカウント(全体、行・列ごと) pandas.DataFrameの行を条件で抽出するquery pandas.DataFrameに列や行を追加(assign, appendなど) 『Pythonデータサイエンスハンドブック』は良書(NumPy, pandasほか) pandas.DataFrameの各列間の相関係数を算出、ヒートマップで可視化 pandas.DataFrameの列をインデックス(行名)に割り当てるset_index pandasの文字列メソッドで置換や空白削除などの処理を行う pandas-datareaderで株価や人口のデータを取得 pandas.DataFrameから特定の型dtypeの列を抽出(選択) pandasで任意の位置の値を取得・変更するat, iat, loc, iloc pandasの時系列データのタイムゾーンを処理(tz_convert, tz_localize)

Last Updated: 6/26/2019, 10:34:03 PM