パンダのDataFrameに「in」と「not in」を実装する方法は?
:パンダは、2つのメソッドを提供していますSeries.isin
し、DataFrame.isin
それぞれ、シリーズおよびデータフレームのために。
1つの列に基づくDataFrameのフィルター処理(シリーズにも適用)
最も一般的なシナリオはisin
、特定の列に条件を適用して、DataFrameの行をフィルター処理することです。
df = pd.DataFrame({'countries': ['US', 'UK', 'Germany', np.nan, 'China']})
df
countries
0 US
1 UK
2 Germany
3 China
c1 = ['UK', 'China'] # list
c2 = {'Germany'} # set
c3 = pd.Series(['China', 'US']) # Series
c4 = np.array(['US', 'UK']) # array
Series.isin
さまざまなタイプを入力として受け入れます。以下は、必要なものを取得するためのすべての有効な方法です。
df['countries'].isin(c1)
0 False
1 True
2 False
3 False
4 True
Name: countries, dtype: bool
# `in` operation
df[df['countries'].isin(c1)]
countries
1 UK
4 China
# `not in` operation
df[~df['countries'].isin(c1)]
countries
0 US
2 Germany
3 NaN
# Filter with `set` (tuples work too)
df[df['countries'].isin(c2)]
countries
2 Germany
# Filter with another Series
df[df['countries'].isin(c3)]
countries
0 US
4 China
# Filter with array
df[df['countries'].isin(c4)]
countries
0 US
1 UK
多くの列でフィルター
場合によっては、複数の列にいくつかの検索用語を含む「in」メンバーシップチェックを適用したい場合があります
df2 = pd.DataFrame({
'A': ['x', 'y', 'z', 'q'], 'B': ['w', 'a', np.nan, 'x'], 'C': np.arange(4)})
df2
A B C
0 x w 0
1 y a 1
2 z NaN 2
3 q x 3
c1 = ['x', 'w', 'p']
isin
条件を列「A」と「B」の両方に適用するには、次を使用しますDataFrame.isin
。
df2[['A', 'B']].isin(c1)
A B
0 True True
1 False False
2 False False
3 False True
これから、少なくとも1つの列がある行を保持するにはTrue
するany
には、最初の軸に沿って使用できます。
df2[['A', 'B']].isin(c1).any(axis=1)
0 True
1 False
2 False
3 True
dtype: bool
df2[df2[['A', 'B']].isin(c1).any(axis=1)]
A B C
0 x w 0
3 q x 3
すべての列を検索する場合は、列の選択手順を省略して、
df2.isin(c1).any(axis=1)
同様に、すべての列がある行を保持するにはTrue
、次を使用します。all
以前と同じ方法します。
df2[df2[['A', 'B']].isin(c1).all(axis=1)]
A B C
0 x w 0
注目すべき言及:numpy.isin
、query
、リストの内包表記(文字列データ)
上記のメソッドに加えて、同等のnumpyを使用することもできます。 numpy.isin
。
# `in` operation
df[np.isin(df['countries'], c1)]
countries
1 UK
4 China
# `not in` operation
df[np.isin(df['countries'], c1, invert=True)]
countries
0 US
2 Germany
3 NaN
なぜそれを検討する価値があるのですか?オーバーヘッドが低いため、NumPy関数は通常、対応するパンダよりも少し高速です。これはインデックスの配置に依存しない要素ごとの操作であるため、このメソッドがパンダの適切な代替ではない状況はほとんどありませんisin
。
文字列操作はベクトル化するのが難しいため、文字列を扱う場合、通常Pandasルーチンは反復的です。ここでは、リスト内包表記がより高速になることを示唆する多くの証拠があります。。in
今、チェックに頼ります。
c1_set = set(c1) # Using `in` with `sets` is a constant time operation...
# This doesn't matter for pandas because the implementation differs.
# `in` operation
df[[x in c1_set for x in df['countries']]]
countries
1 UK
4 China
# `not in` operation
df[[x not in c1_set for x in df['countries']]]
countries
0 US
2 Germany
3 NaN
ただし、指定するのはかなり扱いにくいので、何をしているのか分からない場合は使用しないでください。
最後に、この回答でDataFrame.query
カバーされているものもあります。numexpr FTW!