Cómo realizar operaciones booleanas a sabiendas de elementos en matrices numpy

Por ejemplo, me gustaría crear una máscara que enmascara elementos con valor entre 40 y 60:

foo = np.asanyarray(range(100)) mask = (foo  60) 

Lo que se ve feo, no puedo escribir:

 (foo  60) 

porque termino con:

  ValueError Traceback (most recent call last) ... ----> 1 (foo  60) ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

¿Existe una forma canónica de realizar operaciones booleanas con elementos en matrices numpy que tengan un código atractivo?

¿Has probado esto?

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

Nota: el método __or__ en un objeto sobrecarga el bitwise o el operador ( | ), no el booleano or operador.

Si tiene comparaciones solo dentro de booleanos, como en su ejemplo, puede usar el operador OR a nivel de bits | Según lo sugerido por Jcollado. Pero cuidado, esto puede darte resultados extraños si alguna vez utilizas productos no booleanos, como mask = (foo < 40) | override mask = (foo < 40) | override Solo mientras la override garantizada sea Falso, Verdadero, 1 o 0, está bien.

Más general es el uso de los operadores de conjuntos de comparación de np.any , np.any y np.all . Este fragmento de código devuelve todos los valores entre 35 y 45 que son menos de 40 o no un múltiplo de 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]) 

No tan bonito como con | , pero mejor que el código en su pregunta.

Puede utilizar las operaciones lógicas numpy . En tu ejemplo:

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

Tenga en cuenta que puede usar ~ para la negación elementwise.

 arr = np.array([False, True]) ~arr OUTPUT: array([ True, False], dtype=bool) 

También & hace elementwise y

 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) 

Estos también funcionan con Pandas Series.

 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