Как выполнять элементарные булевы операции над массивами 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, которые с хорошим кодом?

592   4  

4 ответов:

Вы пробовали это?

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

Примечание: метод__or__ в объекте перегружает побитовый оператор or (|), а не булев оператор or.

Если у вас есть сравнения только внутри булевых символов, как в вашем примере, вы можете использовать побитовый оператор OR |, как предлагает Jcollado. Но будьте осторожны, это может дать вам странные результаты, если вы когда-либо используете не булевы, такие как mask = (foo < 40) | override. Только до тех пор, пока override гарантированно будет ложным, истинным, 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

Comments

    Ничего не найдено.