我想通过指定变量一组DataFrame
条件来过滤大熊猫column==value
的行。
我们假设我们有一个像这样的玩具DataFrame
:
from itertools import product
from numpy.random import rand
df = pd.DataFrame([[i,j,k,rand()] for i,j,k,m in product(range(2), repeat=3)],
columns=['par1','par2','par3','val'])
其中一些行看起来像:
par1 par2 par3 val
0 0 0 0 0.464625
1 0 0 1 0.481147
2 0 1 0 0.817992
3 0 1 1 0.639930
4 1 0 0 0.035160
5 1 0 1 0.549517
6 1 1 0 0.172746
7 1 1 1 0.855064
我想知道通过指定某些行来选择某些行的最佳方式是什么
column==value
条件不需要包含所有列,也不总是包含相同列或甚至相同数量的列。我认为dict
是指定条件的一种相当自然的方式:
conditions = {'par1':1, 'par3':0}
在这种情况下,df.par2
的任何值都可以。
df.isin()
我了解df.isin()
dict
个参数以及all(1)
as shown in the docs(该部分的最后一段代码)。问题是,未在df.isin()
调用中通过条件的列中的值会给False
,因此后续调用all(1)
会给出一个空的DataFrame。 (一种方法是将所有可能值作为标准添加所有缺失的列,但它听起来不是一个很好的解决方案)
df.query()
在写这个问题时,我想出了另一个尝试。这个看起来更好:从条件dict
自动构建查询。
df.query(' & '.join(['({} == {})'.format(k,v)
for k,v in conditions.iteritems()]))
它按预期工作......
par1 par2 par3 val
4 1 0 0 0.035160
6 1 1 0 0.172746
尽管如此,我还没有完全相信,我想知道是否有更自然/适当/清晰的方式来做它...熊猫是如此巨大我总是有一种印象我错过了正确的做事的方式......:P
答案 0 :(得分:4)
您可以制作一系列conditions
并仅选择这些列:
>>> df[(df[list(conditions)] == pd.Series(conditions)).all(axis=1)]
par1 par2 par3 val
4 1 0 0 0.937192
6 1 1 0 0.536029
这是有效的,因为在我们制作系列之后,它将我们需要的方式与之比较:
>>> df[list(conditions)]
par1 par3
0 0 0
1 0 1
2 0 0
3 0 1
4 1 0
5 1 1
6 1 0
7 1 1
>>> df[list(conditions)] == pd.Series(conditions)
par1 par3
0 False True
1 False False
2 False True
3 False False
4 True True
5 True False
6 True True
7 True False