我正在使用panda,并且遇到过一些情况,我有一个以编程方式生成的条件列表,比如
conditionals = [
df['someColumn'] == 'someValue',
df['someOtherCol'] == 'someOtherValue',
df['someThirdCol'].isin(['foo','bar','baz']),
]
并且我想要选择所有这些条件都为真的行。我想我会做这样的事。
bigConditional = IHaveNoIdeaOfWhatToPutHere
for conditional in conditionals:
bigConditional = bigConditional && conditional
filteredDf = df[bigConditional]
我知道我想使用identity属性,其中bigConditional对于我的数据帧中的每个索引都初始化为一系列true,这样,如果我的条件列表中的任何条件评估为false,则该行不会出现在筛选的数据框中,但最初会考虑每一行。
我不知道如何做到这一点,或者至少不是最好、最简洁的方式来表明它是有意的
此外,我遇到过一些相反的场景,在这些场景中,我只需要匹配其中一个条件就可以将行包含到新的数据帧中,因此我需要将数据帧中的每个索引的bigConditional设置为false。
对条件求和并检查它是否等于条件的数量
filteredDf = df.loc[sum(conditionals)==len(conditionals)]
或者更简单,使用np.all
filteredDf = df.loc[np.all(conditionals, axis=0)]
否则,对于您最初的问题,您可以创建一系列True索引,如df,您的for
循环应该可以工作。
bigConditional = pd.Series(True, index=df.index)
也许您可以使用query
并生成这样的条件:
conditionals = [
"someColumn == 'someValue'",
"someOtherCol == 'someOtherValue'",
"someThirdCol.isin(['foo', 'bar', 'baz'])",
]
qs = ' & '.join(conditionals)
out = df.query(qs)
或者使用eval
创建布尔值,而不是过滤数据帧:
mask = df.eval(qs)
演示
假设这个数据帧:
>>> df
someColumn someOtherCol someThirdCol
0 someValue someOtherValue foo
1 someValue someOtherValue baz
2 someValue anotherValue anotherValue
3 anotherValue anotherValue anotherValue
>>> df.query(qs)
someColumn someOtherCol someThirdCol
0 someValue someOtherValue foo
1 someValue someOtherValue baz
>>> df.eval(qs)
0 True
1 True
2 False
3 False
dtype: bool
您甚至可以使用f-string或其他模板语言将变量传递到条件列表中。