DataFrameのデータ抽出処理のまとめ。こういうのでいいんだよ的なものなので、細かい内容は他の方の記事を参考にしてください。データ入出力処理はこちら。
逆引き用の分類
何(インデックスor列名or値)を対象にどうやって(抽出条件)データを抽出したいのかにマッチする方法が何かを整理しています。おすすめの選択方法をリンク付きにしました。
抽出条件 | インデックス(ラベル) | 列名 | dfの値 |
---|---|---|---|
= 値 isin 複数の値 |
df.loc df.reindex df.filter df.query df[bools] |
df[] df.loc df.reindex df.filter (df.T.query.T) df[bools] |
df.query df[bools] |
!= 値 not isin 複数の値 |
df.drop df.query df[bools] |
df.drop (df.T.query.T) df[bools] |
df.query df[bools] |
スライス | df.loc | ||
<,≤,>,≥ 値 |
df.query df[bools] |
(df.T.query.T) df[bools] |
df.query df[bools] |
like 値 |
df.filter df.query df[bools] |
df.filter (df.T.query.T) df[bools] |
df.query df[bools] |
正規表現 |
df.filter df.query df[bools] |
df.filter (df.T.query.T) df[bools] |
df.query df[bools] |
関数 |
df.query df[bools] |
(df.T.query.T) df[bools] |
df.query df[bools] |
上記組み合わせ(and,or,not) |
df.query df[bools] |
(df.T.query.T) df[bools] |
df.query df[bools] |
正規表現については以下を参照。
https://qiita.com/luohao0404/items/7135b2b96f9b0b196bf3
以下のデータを対象に、次のセクション以降で具体的なデータ抽出方法を説明します。
df = pd.DataFrame({'都道府県':['千葉県','三重県','北海道','神奈川県'],
'まいわし':[10,20,100,np.nan],
'かたくちいわし':[20,30,60,60],
'あじ':[np.nan,np.nan,100,30]}
).set_index('都道府県')
都道府県 | まいわし | かたくちいわし | あじ |
---|---|---|---|
千葉県 | 10 | 20 | NaN |
三重県 | 20.0 | 30 | NaN |
北海道 | 100.0 | 60 | 100.0 |
神奈川県 | NaN | 60 | 30.0 |
注)上の表の数字に意味はありません。神奈川でまいわしが獲れない訳でも、千葉・三重であじが獲れない訳でもありません。気分を悪くされた方がいたら申し訳ありません。私は神奈川のいわしも、千葉、三重のあじもおいしいと思っています。
DataFrame[]
https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#slicing-ranges
https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#attribute-access
列名 == 値、列名 isin 複数の値
df['まいわし'] # Seriesになる
# 都道府県
# 千葉県 10.0
# 三重県 20.0
# 北海道 100.0
# 神奈川県 NaN
# Name: まいわし, dtype: float64
df[['まいわし']] # DataFrameになる
# 都道府県 まいわし
# 千葉県 10.0
# 三重県 20.0
# 北海道 100.0
# 神奈川県 NaN
df[['まいわし','かたくちいわし']]
# 都道府県 まいわし かたくちいわし
# 千葉県 10.0 20
# 三重県 20.0 30
# 北海道 100.0 60
# 神奈川県 NaN 60
DataFrame.loc
インデックス == 値 、インデックス isin 複数の値
df.loc['千葉県'] #Seriesになる
# まいわし 10.0
# かたくちいわし 20.0
# あじ NaN
# Name: 千葉県, dtype: float64
df.loc[['千葉県']] #DataFrameになる
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
df.loc[['三重県','神奈川県'],:]
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
列名 == 値、 列名 isin 複数の値
df.loc[:,'まいわし'] # Seriesになる
# 都道府県
# 千葉県 10.0
# 三重県 20.0
# 北海道 100.0
# 神奈川県 NaN
# Name: まいわし, dtype: float64
df.loc[:,['まいわし']] # DataFrameになる
# 都道府県 まいわし
# 千葉県 10.0
# 三重県 20.0
# 北海道 100.0
# 神奈川県 NaN
df.loc[:,['まいわし','かたくちいわし']]
# 都道府県 まいわし かたくちいわし
# 千葉県 10.0 20
# 三重県 20.0 30
# 北海道 100.0 60
# 神奈川県 NaN 60
DataFrame.reindex
インデックス isin 複数の値
df.reindex(index=['三重県','神奈川県'])
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
列名 isin 複数の値
df.reindex(columns=['まいわし','かたくちいわし'])
# 都道府県 まいわし かたくちいわし
# 千葉県 10.0 20
# 三重県 20.0 30
# 北海道 100.0 60
# 神奈川県 NaN 60
DataFrame.drop
インデックス not isin 複数の値
df.drop(index=['千葉県','北海道'])
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
列名 not isin 複数の値
df.drop(columns=['あじ'])
# 都道府県 まいわし かたくちいわし
# 千葉県 10.0 20
# 三重県 20.0 30
# 北海道 100.0 60
# 神奈川県 NaN 60
DataFrame.filter
インデックス isin 複数の値
df.filter(items=['三重県','神奈川県'],axis=0) # df.loc[['三重県','神奈川県']]と同じ
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
列名 isin 複数の値
df.filter(items=['まいわし','かたくちいわし']) # df[['まいわし','かたくちいわし']]と同じ
# 都道府県 まいわし かたくちいわし
# 千葉県 10.0 20
# 三重県 20.0 30
# 北海道 100.0 60
# 神奈川県 NaN 60
インデックス like 値
df.filter(like='県',axis=0)
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
列名 like 値
df.filter(like='いわし',axis=1)
# 都道府県 まいわし かたくちいわし
# 千葉県 10.0 20
# 三重県 20.0 30
# 北海道 100.0 60
# 神奈川県 NaN 60
正規表現 search インデックス
df.filter(regex='^..県',axis=0)
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
正規表現 search 列名
df.filter(regex='.*いわ',axis=1)
# 都道府県 まいわし かたくちいわし
# 千葉県 10.0 20
# 三重県 20.0 30
# 北海道 100.0 60
# 神奈川県 NaN 60
DataFrame.query
- https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.query.html#pandas.DataFrame.query
- https://note.nkmk.me/python-pandas-query/
インデックス(or dfの値) == 値、インデックス(or dfの値) isin 複数の値
df.query('都道府県=="千葉県"') # df.query('index=="千葉県")でもOK
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
df.query('都道府県 in ["三重県","神奈川県"]') #df.query('都道府県==[...])でもOK
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
# NaNの場合は注意
df.query('まいわし.isna()', engine='python') #df.query('まいわし!=まいわし')でもOK(分かりにくいけど)
# 都道府県 まいわし かたくちいわし あじ
# 神奈川県 NaN 60 30.0
インデックス(or dfの値) != 値、インデックス(or dfの値) not isin 複数の値
hokkaido = '北海道'
df.query('都道府県!=@hokkaido') #@で変数使用可
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
chi_hok = ['千葉県','北海道']
df.query('都道府県 not in @chi_hok')
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
# NaNの場合は注意
df.query('まいわし.notna()', engine='python') #df.query('まいわし==まいわし')でもOK(分かりにくいけど)
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
# 北海道 100.0 60 100.0
インデックス(or dfの値) <,≤,>,≥ 値
df.query('まいわし>0')
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
# 北海道 100.0 60 100.0
インデックス(or dfの値) like 値
df.query('index.str.contains("道")', engine='python')
# 都道府県 まいわし かたくちいわし あじ
# 北海道 100.0 60 100.0
正規表現 match インデックス(or dfの値)
df.query('index.str.match("^..県")', engine='python')
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
関数(インデックス(or dfの値))
上の例で@を付けて変数を渡しましたが、関数を渡せば任意の関数を使って抽出できます。
def is_thirty(x):
if type(x)==str:
return x.find('三重')>-1
elif str(x).isdigit():
return x==30
else:
return False
df.query('index.apply(@is_thirty)', engine='python')
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
df.query('かたくちいわし.apply(@is_thirty)', engine='python')
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
インデックス(or dfの値) の条件組み合わせ
df.query('まいわし>0 and あじ > 0')
# 都道府県 まいわし かたくちいわし あじ
# 北海道 100.0 60 100.0
df.query('not まいわし>0')
# 都道府県 まいわし かたくちいわし あじ
# 神奈川県 NaN 60 30.0
DataFrame[bools]
DataFrame[bools]は私の勝手な表現です。df[]やdf.loc[]にboolのリストを渡すと、Trueのものだけが抽出されるので、そのように書いています。詳しくは以下を参照してください。
Python pandas データ選択処理をちょっと詳しく <中編>
インデックス == 値
df[df.index=='千葉県'] # df.loc[df.index=='千葉県']でもOK
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
インデックス isin 複数の値
df[df.index.isin(['三重県','神奈川県'])] #df.loc[df.index.isin(['三重県','神奈川県'])]でもOK
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
列名 == 値
df.loc[:,df.columns=='あじ'] #df[['あじ']]と同じ
# 都道府県 あじ
# 千葉県 NaN
# 三重県 NaN
# 北海道 100.0
# 神奈川県 30.0
列名 isin 複数の値
df.loc[:,df.columns.isin(['まいわし','かたくちいわし'])] #df[['まいわし','かたくちいわし']]と同じ
# 都道府県 まいわし かたくちいわし
# 千葉県 10.0 20
# 三重県 20.0 30
# 北海道 100.0 60
# 神奈川県 NaN 60
dfの値 == 値
df[df['あじ']==30] # df.loc[df['あじ']==30]でもOK
# 都道府県 まいわし かたくちいわし あじ
# 神奈川県 NaN 60 30.0
dfの値 isin 複数の値
df[df['かたくちいわし'].isin([20,30])] # df.loc[df['かたくちいわし'].isin([20,30])]でもOK
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
インデックス != 値
df[df.index !='北海道'] # []内は、~(df.index='北海道')でもnp.logical_not(df.index='北海道')でもOK。というかdropを使おう。
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
インデックス not isin 複数の値
df[~(df.index.isin(['千葉県','北海道']))] # dropを使おう。
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
# 神奈川県 NaN 60 30.0
列名 != 値
df.loc[:,df.columns !='あじ'] # []内は、~(df.clumns='あじ')でもnp.logical_not(df.index='あじ')でもOK。というかdropを使おう。
# 都道府県 まいわし かたくちいわし
# 千葉県 10.0 20
# 三重県 20.0 30
# 北海道 100.0 60
# 神奈川県 NaN 60
列名 not isin 複数の値
df.loc[:,~(df.columns.isin(['まいわし','かたくちいわし']))] # dropを使おう
# 都道府県 あじ
# 千葉県 NaN
# 三重県 NaN
# 北海道 100.0
# 神奈川県 30.0
dfの値 != 値
df[df['あじ'] != 30]
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
# 北海道 100.0 60 100.0
dfの値 not isin 複数の値
df[~(df['あじ'].isin([30,100]))]
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
インデックス(or 列名、dfの値) <,≤,>,≥ 値
df[df['まいわし']>0] #dfの値の場合。インデックスの場合はdf.index、列名の場合はdf.columnで条件判定。
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
# 北海道 100.0 60 100.0
インデックス(or 列名、dfの値) like 値
df[df.index.str.contains('道')] #インデックスの場合。列名の場合はdf.column、dfの値の場合はdf[列名]に.str.containsをつなげる。
# 都道府県 まいわし かたくちいわし あじ
# 北海道 100.0 60 100.0
正規表現 match インデックス(or 列名、dfの値)
df[df.index.str.match('^..県')] #インデックスの場合。列名の場合はdf.column、dfの値の場合はdf[列名]に.str.matchをつなげる。
# 都道府県 まいわし かたくちいわし あじ
# 千葉県 10.0 20 NaN
# 三重県 20.0 30 NaN
関数(インデックス(or 列名、dfの値) )
def is_thirty(x):
if type(x)==str:
return x.find('三重')>-1
elif str(x).isdigit():
return x==30
else:
return False
df[df.index.map(is_thirty)] # applyは使えない
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
df[df['かたくちいわし'].apply(is_thirty)]
# 都道府県 まいわし かたくちいわし あじ
# 三重県 20.0 30 NaN
インデックス(or 列名、dfの値) の条件組み合わせ
df[(df['まいわし']>0) & (df['あじ']>0)] # df.query('まいわし>0 and あじ > 0')と同じ
# 都道府県 まいわし かたくちいわし あじ
# 北海道 100.0 60 100.0
df[~(df['まいわし']>0)]
# 都道府県 まいわし かたくちいわし あじ
# 神奈川県 NaN 60 30.0
df.loc[df['まいわし']>0,df.columns.str.contains('いわし')] #インデックスとdfの値のboolsは&や|でつなげても良いが、列名のboolsとその他はつなげられない。locの別の引数として設定する。
# 都道府県 まいわし かたくちいわし
# 千葉県 10.0 20
# 三重県 20.0 30
# 北海道 100.0 60
DataFrame.xs