python - 带和不带括号的 pandas 逻辑和运算符产生不同的结果

标签 python pandas

<分区>

我刚注意到:

df[df.condition1 & df.condition2]
df[(df.condition1) & (df.condition2)]

为什么这两行的输出不同?


我不能分享确切的数据,但我会尽力提供尽可能多的细节:

df[df.col1 == False & df.col2.isnull()] # returns 33 rows and the rule `df.col2.isnull()` is not in effect
df[(df.col1 == False) & (df.col2.isnull())] # returns 29 rows and both conditions are applied correctly 

感谢@jezrael 和@ayhan,这是发生的事情,让我使用@jezael 提供的示例:

df = pd.DataFrame({'col1':[True, False, False, False],
                   'col2':[4, np.nan, np.nan, 1]})

print (df)
    col1  col2
0   True   4.0
1  False   NaN
2  False   NaN
3  False   1.0

如果我们看一下第 3 行:

    col1  col2
3  False   1.0

以及我写条件的方式:

df.col1 == False & df.col2.isnull() # is equivalent to False == False & False

因为 & 符号比 == 有更高的优先级,没有括号 False == False & False 等同于:

False == (False & False)
print(False == (False & False)) # prints True

带括号:

print((False == False) & False) # prints False

我认为用数字来说明这个问题更容易一些:

print(5 == 5 & 1) # prints False, because 5 & 1 returns 1 and 5==1 returns False
print(5 == (5 & 1)) # prints False, same reason as above
print((5 == 5) & 1) # prints 1, because 5 == 5 returns True, and True & 1 returns 1

所以吸取教训:总是加括号!!!

我希望我可以将答案分给@jezrael 和@ayhan :(

最佳答案

df[condition1 & condition2]df[(condition1) & (condition2)] 没有区别。当您编写表达式并且运算符 & 优先时,就会出现差异:

df = pd.DataFrame(np.random.randint(0, 10, size=(5, 3)), columns=list('abc'))    
df
Out: 
   a  b  c
0  5  0  3
1  3  7  9
2  3  5  2
3  4  7  6
4  8  8  1

condition1 = df['a'] > 3
condition2 = df['b'] < 5

df[condition1 & condition2]
Out: 
   a  b  c
0  5  0  3

df[(condition1) & (condition2)]
Out: 
   a  b  c
0  5  0  3

但是,如果您这样输入,您会看到一个错误:

df[df['a'] > 3 & df['b'] < 5]
Traceback (most recent call last):

  File "<ipython-input-7-9d4fd21246ca>", line 1, in <module>
    df[df['a'] > 3 & df['b'] < 5]

  File "/home/ayhan/anaconda3/lib/python3.5/site-packages/pandas/core/generic.py", line 892, in __nonzero__
    .format(self.__class__.__name__))

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

这是因为首先对 3 & df['b'] 求值(这对应于示例中的 False & df.col2.isnull())。所以你需要将条件分组在括号中:

df[(df['a'] > 3) & (df['b'] < 5)]
Out[8]: 
   a  b  c
0  5  0  3

关于python - 带和不带括号的 pandas 逻辑和运算符产生不同的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42338005/

相关文章:

python - 使用通用 View 时模板不存在

python - Pygame 中的箭头键移动

python - 如何使用 python 电子邮件获取解码附件文件名?

Python Pandas lambda 函数更改列的所有值?

python - 通过引用传递可变对象?

javascript - 如何编写一个使用 HTML 和 CSS 作为用户界面并使用 python/perl/c++/java 进行处理的桌面应用程序?

Python:有吸引力的、干净的、可打包的 Windows GUI 库

python - 如何在复杂的情况下获得假人

python - 如何从 pandas 数据集中创建网格大小不均匀的热图?

python - 使用 ELEMNTREE 和 Beautifulsoup 解析 XML 时遇到内存问题