pandas:选择符合多个条件的所有行

时间:2015-01-15 22:07:42

标签: python pandas

我有以下数据框:

 >>> df = pd.DataFrame({'col1': [1, 2, 1], 'col2': [6, 3, 6]})
 >>> df
    col1  col2
  0     1     6
  1     2     3
  2     1     6

和以下词典:

 >>> di = {'col1': 1, 'col2': 6}
 >>> di
 {'col2': 6, 'col1': 1}

我正在寻找能够遍历 di 的解决方案,并在 df 中找到匹配的行。我不想写一行专门使用列名和值的行。我在论坛上看到了这些解决方案,这不是我想在这里做的。 (可怕的非)解决方案是:

 is_not_first = True
 tf_series = None
 for key, val in di.iteritems():
      if is_not_first:
           tf_series = (tf_series & (df[key] == val))
      else:
           tf_series = (df[key] == val)
           is_not_first = False

我打算稍后使用 tf_series df 中设置另一列:

 df.loc[tf_series, 'col3'] = True

从我见过的许多优秀的熊猫帖子来看,我确信有更简洁的东西,更不用说,实际上有用的东西。谢谢!

1 个答案:

答案 0 :(得分:3)

您可以将所有逻辑合并为一行,而不是构建冗余系列,您可以构建另一个与 df 具有相同索引/列的DataFrame并分配给{{1}直接,这是实现这一目标的一种方法:

df['col3']

使用地图

的快速和缺省版本
In [1]: import pandas as pd

In [2]: df = pd.DataFrame({'col1': [1, 2, 1], 'col2': [6, 3, 6]})

In [3]: di = {'col1': 1, 'col2': 6}

In [4]: df['col3'] = pd.DataFrame([df[k]==v for k,v in di.iteritems()]).all()

In [5]: df
Out[5]: 
   col1  col2   col3
0     1     6   True
1     2     3  False
2     1     6   True

细分说明

如果您查看列表,当您重复字典 di 时,它会为您提供键/值对,这实际上是是原始 df 的列/值。 因此,In [6]: df['col3'] = pd.DataFrame(map(lambda k: df[k]==di[k], di)).all() 会为您提供价值,并将其与字典' v 进行比较,产生真/假

df[column]

然后根据该结果构建一个阴影DataFrame,将为您提供:

In [8]: [df[k]==v for k,v in di.iteritems()]
Out[8]: 
[0     True
 1    False
 2     True
 Name: col2, dtype: bool, 0     True
 1    False
 2     True
 Name: col1, dtype: bool]

修改

正如@ant指出的那样,我错误地使用了 any(),而 all()则应该满足所有pd.DataFrame([df[k]==v for k,v in di.iteritems()]) Out[9]: 0 1 2 col2 True False True col1 True False True 值:< / p>

最后,所有()返回索引/结果,其上方的列符合所有 True 条件:

True

您只需将此结果列指定给In [10]: pd.DataFrame([df[k]==v for k,v in di.iteritems()]).all() Out[10]: 0 True 1 False 2 True dtype: bool ,即可完成。

要避免df['col3']警告,您只需要将一个班轮分成2:

SettingWithCopy