Python 熊猫:索引数据帧时出现多个条件-意外行为

Python 熊猫:索引数据帧时出现多个条件-意外行为,python,pandas,boolean-logic,Python,Pandas,Boolean Logic,我通过两列中的值过滤数据帧中的行 出于某种原因,OR运算符的行为与我期望的和运算符的行为相同,反之亦然 我的测试代码: import pandas as pd df = pd.DataFrame({'a': range(5), 'b': range(5) }) # let's insert some -1 values df['a'][1] = -1 df['b'][1] = -1 df['a'][3] = -1 df['b'][4] = -1 df1 = df[(df.a != -1)

我通过两列中的值过滤数据帧中的行

出于某种原因,OR运算符的行为与我期望的和运算符的行为相同,反之亦然

我的测试代码:

import pandas as pd

df = pd.DataFrame({'a': range(5), 'b': range(5) })

# let's insert some -1 values
df['a'][1] = -1
df['b'][1] = -1
df['a'][3] = -1
df['b'][4] = -1

df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a != -1) | (df.b != -1)]

print pd.concat([df, df1, df2], axis=1,
                keys = [ 'original df', 'using AND (&)', 'using OR (|)',])
结果是:

      original df      using AND (&)      using OR (|)    
             a  b              a   b             a   b
0            0  0              0   0             0   0
1           -1 -1            NaN NaN           NaN NaN
2            2  2              2   2             2   2
3           -1  3            NaN NaN            -1   3
4            4 -1            NaN NaN             4  -1

[5 rows x 6 columns]
如您所见,
运算符会删除至少一个值等于
-1
的每一行。另一方面,
运算符要求两个值都等于
-1
,才能删除它们。我预期的结果恰恰相反。有人能解释一下这种行为吗

我使用的是熊猫0.13.1

如您所见,AND运算符删除至少有一个 值等于-1。另一方面,OR运算符同时需要这两个参数 值等于-1以删除它们

对。记住,你写的条件是你想保留什么,而不是你想放弃什么。对于
df1

df1 = df[(df.a != -1) & (df.b != -1)]
您的意思是“保留
df.a
不是-1且
df.b
不是-1的行”,这与删除至少一个值为-1的每一行相同

对于
df2

df2 = df[(df.a != -1) | (df.b != -1)]
您的意思是“保留
df.a
df.b
不是-1的行”,这与删除两个值都是-1的行相同

注:像
df['a'][1]=-1
这样的链式访问会让你陷入麻烦。最好养成使用
.loc
.iloc

的习惯,也可以使用,即:


一点数学逻辑理论这里:

“非a非b”与“非(a或b)”相同,因此:

“a NOT-1和b NOT-1”相当于“NOT(a is-1或b is-1)”,与“(a is-1或b is-1)”相反(补语)

因此,如果您想要完全相反的结果,df1和df2应如下所示:

df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a == -1) | (df.b == -1)]

DataFrame.query()
在这里也能很好地工作
df.query('a!=-1或b!=-1')
。碰巧知道为什么熊猫想要
&
|
超过
?@stoves:在普通Python代码中,
具有无法修改的基本Python语义<另一方面,code>&
|
有相应的特殊方法来控制它们的行为。(当然,在查询字符串中,我们可以自由地应用任何我们喜欢的语法分析。)有趣的是,似乎
df[True&False]
失败了,但
df[(True)和(False)]
成功了(本例中未测试)是否可以跨多行中断这种语法?什么是最适合PEP8?
df.query
pd.eval
似乎非常适合这个用例。有关
pd.eval()
函数系列及其特性和用例的信息,请访问。我认为这种语法更有意义,例如:df.query(“”(a==4&b!=2)| c==3”)
df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a == -1) | (df.b == -1)]