例如,我想创建一个掩盖值为40到60之间的元素的掩码:
foo = np.asanyarray(range(100))
mask = (foo < 40).__or__(foo > 60)
哪个看起来很难看,我写不出来:
(foo < 40) or (foo > 60)
因为我最终得到了:
ValueError Traceback (most recent call last)
...
----> 1 (foo < 40) or (foo > 60)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
是否有规范的方法在numpy数组上进行元素明智的布尔运算,具有良好的代码?
答案 0 :(得分:69)
你试过这个吗?
mask = (foo < 40) | (foo > 60)
注意:对象中的__or__
方法会重载按位或运算符(|
),而不会重载布尔or
运算符。
答案 1 :(得分:15)
如果您只在布尔值内进行比较,如您的示例所示,您可以使用Jcollado建议的按位OR运算符|
。但要注意,如果您使用非布尔值,例如mask = (foo < 40) | override
,这可能会给您带来奇怪的结果。只要override
保证为False,True,1或0,你就没事了。
更一般的是使用numpy的比较集运算符np.any
和np.all
。此代码段返回35到45之间的所有值,小于40或不是3的倍数:
import numpy as np
foo = np.arange(35, 46)
mask = np.any([(foo < 40), (foo % 3)], axis=0)
print foo[mask]
OUTPUT: array([35, 36, 37, 38, 39, 40, 41, 43, 44])
不如|
那么好,但比你问题中的代码更好。
答案 2 :(得分:9)
您可以使用numpy logical operations。在您的示例中:
np.logical_or(foo < 40, foo > 60)
答案 3 :(得分:3)
请注意,您可以使用~
进行元素否定。
arr = np.array([False, True])
~arr
OUTPUT: array([ True, False], dtype=bool)
此外&
还有元素和
arr_1 = np.array([False, False, True, True])
arr_2 = np.array([False, True, False, True])
arr_1 & arr_2
OUTPUT: array([False, False, False, True], dtype=bool)
这些也适用于 Pandas 系列
ser_1 = pd.Series([False, False, True, True])
ser_2 = pd.Series([False, True, False, True])
ser_1 & ser_2
OUTPUT:
0 False
1 False
2 False
3 True
dtype: bool