pandas:索引数据框时的多个条件 - 意外行为

Woj*_*zak 100 python boolean-logic pandas

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

由于某种原因,OR运算符的行为与我期望AND运算符的行为相反,反之亦然.

我的测试代码:

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 (|)',])
Run Code Online (Sandbox Code Playgroud)

结果如下:

      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]
Run Code Online (Sandbox Code Playgroud)

如您所见,AND运算符会丢弃至少一个值等于的每一行-1.另一方面,OR运算符要求两个值都等于-1丢弃它们.我期望完全相反的结果.有人能解释一下这种行为吗?

我正在使用熊猫0.13.1.

DSM*_*DSM 159

如您所见,AND运算符删除其中至少有一个值等于-1的每一行.另一方面,OR运算符要求两个值都等于-1才能删除它们.

那就对了.请记住,您根据自己想要保留的内容来编写条件,而不是根据要删除的内容.用于df1:

df1 = df[(df.a != -1) & (df.b != -1)]
Run Code Online (Sandbox Code Playgroud)

你说的是"保持行df.a不在-1并且df.b不是-1",这与删除其中至少有一个值为-1的每一行相同.

用于df2:

df2 = df[(df.a != -1) | (df.b != -1)]
Run Code Online (Sandbox Code Playgroud)

你说的是"保持行中的任何一个df.adf.b不是-1",这与删除两个值为-1的行相同.

PS:链接访问就像df['a'][1] = -1可以让你陷入困境.养成使用.loc和使用习惯更好.iloc.

  • `DataFrame.query()`在这里也很好用.`df.query('a!= -1或b!= -1')`. (15认同)
  • 发生了解为什么大熊猫想要`&`和`|`而不是`和`以及`或`? (3认同)
  • 是否有可能在多行中打破这种语法?什么是最 PEP8? (3认同)
  • @stoves:在普通的Python代码中,`和`和`或`具有无法修改的基本Python语义.另一方面,`&`和`|`有相应的特殊方法来控制它们的行为.(在查询字符串中,当然,我们可以自由地应用任何我们喜欢的解析.) (2认同)

Ped*_*ito 37

你可以使用query(),即:

df_filtered = df.query('a == 4 & b != 2')
Run Code Online (Sandbox Code Playgroud)


小智 7

这里有一些数学逻辑理论

“ NOT a AND NOT b”“ NOT(a OR b)”相同,因此:

“ a NOT -1 AND b NOT -1” 等同于 “ NOT(a为-1 OR b为-1)”,与“(a is -1 OR b为-1)”的(补码)相反。

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

df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a == -1) | (df.b == -1)]
Run Code Online (Sandbox Code Playgroud)