我正在使用 Pandas 中的布尔索引。
问题是为什么声明:
a[(a['some_column']==some_number) & (a['some_other_column']==some_other_number)]
工作正常而
a[(a['some_column']==some_number) and (a['some_other_column']==some_other_number)]
错误退出?
例子:
a = pd.DataFrame({'x':[1,1],'y':[10,20]})
In: a[(a['x']==1)&(a['y']==10)]
Out: x y
0 1 10
In: a[(a['x']==1) and (a['y']==10)]
Out: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
原文由 user2988577 发布,翻译遵循 CC BY-SA 4.0 许可协议
当你说
您隐含地要求 Python 将
(a['x']==1)
和(a['y']==10)
转换为布尔值。NumPy 数组(长度大于 1)和 Pandas 对象(例如 Series)没有布尔值——换句话说,它们引发
当用作布尔值时。那是因为 不清楚什么时候应该是 True 或 False 。如果它们的长度不为零,一些用户可能会认为它们是 True,例如 Python 列表。其他人可能希望它只有在 所有 元素都为真时才为真。如果其中 任何 元素为真,其他人可能希望它为真。
由于存在太多相互冲突的期望,NumPy 和 Pandas 的设计者拒绝猜测,而是引发 ValueError。
相反,您必须通过调用
empty()
、all()
或any()
方法来表明您想要的行为。然而,在这种情况下,您似乎不需要布尔值求值,您需要 逐元素 逻辑与。这就是
&
二元运算符执行的操作:返回一个布尔数组。
顺便说一下,正如 alexpmil 指出 的那样,括号是强制性的,因为
&
的 运算符优先级 高于==
。如果没有括号,
a['x']==1 & a['y']==10
将被评估为a['x'] == (1 & a['y']) == 10
这反过来相当于链式比较(a['x'] == (1 & a['y'])) and ((1 & a['y']) == 10)
这是Series and Series
形式的表达式。使用and
与两个系列将再次触发相同的ValueError
如上所述。这就是为什么括号是强制性的。