如何对 NumPy 数组执行元素布尔操作

例如,我想创建一个掩码,它用值在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 数组进行元素布尔运算?

115387 次浏览

试试这个:

mask = (foo < 40) | (foo > 60)

注意: 对象中的 __or__方法重载按位或操作符(|) ,而不是布尔 or操作符。

如果只在布尔值内进行比较,如本例所示,则可以使用 Jcolado 建议的按位 OR 运算符 |。但是请注意,如果您使用非布尔值,比如 mask = (foo < 40) | override,这可能会给您带来奇怪的结果。只要 override保证为 False、 True、1或0,你就没事。

更一般的是使用 NumPy 的比较集运算符 np.anynp.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])

它不像 |那样好,但是比你问题中的代码好。

请注意,可以使用 ~进行元素否定。

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)

这些也适用于 熊猫系列

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

你可以使用 NumPy 逻辑运算。在你的例子中:

np.logical_or(foo < 40, foo > 60)