如何为 pandas DataFrame 实现“in”和“not in”?
Pandas 提供了两种方法:Series.isin分别DataFrame.isin用于 Series 和 DataFrames。
基于 ONE Column 过滤 DataFrame(也适用于 Series)
最常见的场景是在特定列上应用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
由此,要保留至少一列为 的行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)
同样,要保留所有列所在的行,Trueall请以与以前相同的方式使用。
df2[df2[['A', 'B']].isin(c1).all(axis=1)]
   A  B  C
0  x  w  0
Notable Mentions: numpy.isin, query, list comprehensions (string data)
除了上述方法之外,您还可以使用 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 函数通常比它们的 pandas 等效函数快一点。由于这是一个不依赖于索引对齐的元素操作,因此很少有这种方法不适合替代 pandas 的情况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中已经涵盖的内容。数字表达式 FTW!