我有两个pandas代码片段,我认为应该是等效的,但第二个不能达到我的预期。
# snippet 1
data = all_data[[((np.isfinite(all_data[self.design_metric][i])
and all_data['Source'][i] == 2))
or ((np.isfinite(all_data[self.actual_metric][i])
and all_data['Source'][i] != 2))
for i in range(len(all_data))]]
# snippet 2
data = all_data[(all_data['Source'] == 2 &
np.isfinite(all_data[self.design_metric])) |
(all_data['Source'] != 2 &
np.isfinite(all_data[self.actual_metric]))]
每个部分(例如all_data['Source'] == 2
)都能达到我自己的期望,但似乎我对逻辑运算符做错了,因为最终结果会出现与列表理解版本不同的结果
答案 0 :(得分:9)
&
运算符比==
(或任何比较运算符)绑定得更紧密。见the documentation。一个更简单的例子是:
>>> 2 == 2 & 3 == 3
False
这是因为它被分组为2 == (2 & 3) == 3
,然后调用比较链。这就是你的情况。你需要在每次比较中加上括号。
data = all_data[((all_data['Source'] == 2) &
np.isfinite(all_data[self.design_metric])) |
((all_data['Source'] != 2) &
np.isfinite(all_data[self.actual_metric]))]
请注意==
和!=
比较周围的额外括号。
答案 1 :(得分:1)
除优先级外,AND和&之间存在差异。运算符,第一个是布尔值,后者是二进制按位。此外,您必须了解布尔表达式。
请参阅以下代码段中的示例:
逻辑表达式
>>> 1 and 2
1
>>> '1' and '2'
'1'
>>> 0 == 1 and 2 == 0 or 0
0
按位运算符
>>> 1 & 2
0
>>> '1' & '2'
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for &: 'str' and 'str'
>>> 0 == 1 & 2 == 0 | 0
True