Как выполнять элементные логические операции над массивами 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 с хорошим кодом?
4 ответов
вы пробовали это?
mask = (foo < 40) | (foo > 60)
Примечание:__or__
метод в объекте перегружает побитовый оператор or (|
), а не логическое or
оператора.
если у вас есть сравнения только внутри логических значений, как в вашем примере, вы можете использовать побитовый оператор OR |
как предложено Jcollado. Но будьте осторожны, это может дать вам странные результаты если вы когда-либо использовать логические значения, такие как 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])
Не так хорошо, как с |
, но лучше, чем код в ваш вопрос.
можно использовать numpy логические операции. В вашем примере:
np.logical_or(foo < 40, foo > 60)
обратите внимание, что вы можете использовать ~
для элементарного отрицания.
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