我正在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()
当你说
(a['x']==1) and (a['y']==10)
你暗中要求Python进行转换(a['x']==1)并转换(a['y']==10)为布尔值。
(a['x']==1)
(a['y']==10)
NumPy数组(长度大于1)和Pandas对象(例如Series)没有布尔值-换句话说,它们引发
Pandas
Series
ValueError: The truth value of an array is ambiguous. Use a.empty, a.any() or a.all().
当用作布尔值时。那是因为不清楚何时应该为True或False。如果某些用户的长度非零,则可能会认为它们为True,例如Python列表。其他人可能只希望其所有元素均为True 才希望它为True。如果其他任何元素为True,则其他人可能希望它为True。
由于期望值如此之多,因此NumPy和Pandas的设计师拒绝猜测,而是提出了ValueError。
NumPy
ValueError
相反,你必须是明确的,通过调用empty(),all()或any()方法来表示你的愿望是什么行为。
empty()
all()
any()
但是,在这种情况下,你似乎不希望布尔值求值,而是希望按元素进行逻辑与。这就是&二进制运算符执行的操作:
(a['x']==1) & (a['y']==10)
返回一个布尔数组。
顺便说一句,正如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与两个Series一起使用将再次触发与ValueError上述相同的操作。这就是为什么括号是强制性的。
a['x']==1 & a['y']==10
a['x'] == (1 & a['y']) == 10
(a['x'] == (1 & a['y'])) and ((1 & a['y']) == 10)