St_Hakky’s blog

Data Science / Human Resources / Web Applicationについて書きます

PandasのDataFrame / Seriesでリスト内の要素にマッチする or しない行 (row) だけ取り出す

こんにちは。

今日はpandasのメモを。

〇やりたいこと

listとかでよくやる以下みたいな判定をやりたいんです。

list_data = [1,2,3,4,5]

if 1 in list_data:
  print('あります')
else:
  print('ありませんでした')

このような、in演算子を用いて、リスト内に含まれている要素であるかどうかという判定を行い、pandasのマッチした or していない行だけ取り出したいんです。

つまり、pandasだと以下のようなことをやりたいイメージです。

# 当然ですが、以下のコードはエラーが起きます。
import pandas as pd
data = pd.DataFrame({'a': [1,2,3,4,5], 'b': [1,2,3,4,5]})

new_data = data[data['a'] in [1,2]]
# エラー
# ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

これどうやってやるんだろうと思って調べていたんですが、やり方を見つけました。

〇リスト内の要素にマッチ”する”rowを取得する

さて、どうやってやるかなんですが、以下のようにしてやります。

import pandas as pd
data = pd.DataFrame({'a': [1,2,3,4,5], 'b': [1,2,3,4,5]})

new_data = data[data['a'].isin([1,2])]
print(new_data)

isin()を使うんですね、なるほどという感じです。これの出力は、以下のような感じです。

   a  b
0  1  1
1  2  2

〇リスト内の要素にマッチ”しない”rowを取得する

次にマッチ"しない"rowの取得ですが、以下のようにやります。

import pandas as pd
data = pd.DataFrame({'a': [1,2,3,4,5], 'b': [1,2,3,4,5]})

new_data = data[~data['a'].isin([1,2])]
print(new_data)


前に~をつけると、マッチしないものがでに入るそうです(おまえそこは、isnotinとかじゃないのかよと思った人私の友達です)。

これの出力は以下のような感じです。

   a  b
2  3  3
3  4  4
4  5  5

〇そのほかの使い方について

上の例はいずれもSeriesに対してisinを使用し、DataFrameから対象の列を取ってくる例でしたが、DataFrameに大してもisinは使えます。

詳しくは公式ドキュメントを参照。


それでは。