Pandas:多条件过滤

42

我正在尝试使用Pandas进行一些布尔索引,并使用一些条件。我的原始数据框称为df。如果我执行以下操作,将会得到期望的结果:

temp = df[df["bin"] == 3]
temp = temp[(~temp["Def"])]
temp = temp[temp["days since"] > 7]
temp.head()

然而,如果我执行这个操作(我认为应该是等效的),我将得到零行返回:

temp2 = df[df["bin"] == 3]
temp2 = temp2[~temp2["Def"] & temp2["days since"] > 7]
temp2.head()

你知道什么原因导致这种差异吗?

4个回答

74

使用()是由于运算符优先级:

temp2 = df[~df["Def"] & (df["days since"] > 7) & (df["bin"] == 3)]

或者,将条件创建在单独的行中:

cond1 = df["bin"] == 3    
cond2 = df["days since"] > 7
cond3 = ~df["Def"]

temp2 = df[cond1 & cond2 & cond3]

示例:

df = pd.DataFrame({'Def':[True] *2 + [False]*4,
                   'days since':[7,8,9,14,2,13],
                   'bin':[1,3,5,3,3,3]})

print (df)
     Def  bin  days since
0   True    1           7
1   True    3           8
2  False    5           9
3  False    3          14
4  False    3           2
5  False    3          13


temp2 = df[~df["Def"] & (df["days since"] > 7) & (df["bin"] == 3)]
print (temp2)
     Def  bin  days since
3  False    3          14
5  False    3          13

这些示例真的让事情变得更好了! - Anton vBR
没有第一个条件的括号?这对我来说似乎改变了一些东西。 - khhc
1
如果您有一个大型的DataFrame,每个条件都会过滤完整的DataFrame。您能否通过链接过滤器来逐步减少搜索空间?例如,将第一个应用于结果,将第二个应用于结果,...? - wwii
如果数据框非常大,那么@wwii是正确的。首先按条件过滤以删除大部分行,然后将其分配给数据框。接着再进行第二次类似的过滤... - jezrael
@wwii 这里的意思是 temp1 = df[df["bin"] == 3] temp2 = temp1[temp1["days since"] > 7] temp3 = temp2[~temp2["Def"]] - jezrael
1
当你有大量的条件值时,什么是高效的方法呢?例如,df[(df.col1==0) & (df.col2==1) & (df.col3==1)] 有三个列条件,但如果有50个列条件怎么办?是否有一种简单的方法,将列和条件值作为两个列表放入其中?可以使用像 column_list= df.columns[11:61] value_list= 'a list of 50 values' df[df[column_list]== value_list] 这样更简单的方法。 - Tanzin Farhat

11

或者

 df_train[(df_train["fold"]==1) | (df_train["fold"]==2)]

AND

 df_train[(df_train["fold"]==1) & (df_train["fold"]==2)]

2
虽然这段代码可能提供了问题的解决方案,但最好添加上为什么/如何运作的上下文。这可以帮助未来的用户学习,并将这些知识应用到他们自己的代码中。当代码被解释时,您还可能会得到用户的积极反馈,例如点赞。 - Amit Verma

3

另一种方法是使用 query 方法:

df.query('not Def & (`days since` > 7) & (bin == 3)')

1
如果你想要多个条件:
Del_Det_5k_top_10 = Del_Det[(Del_Det['State'] == 'NSW') & (Del_Det['route'] == 2) |
                            (Del_Det['State'] == 'VIC') & (Del_Det['route'] == 3)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接