2011-12-25 47 views
36

Por ejemplo, me gustaría crear una máscara que oculta los elementos con valor de entre 40 y 60:Cómo realizar operaciones booleanas elemento prudentes en matrices numpy

foo = np.asanyarray(range(100)) 
mask = (foo < 40).__or__(foo > 60) 

Lo cual se ve mal, no puedo escribir:

(foo < 40) or (foo > 60) 

porque termino con:

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() 

¿hay una manera de hacer canónica elemento sabia ope booleano raciones en matrices numpy que con buen aspecto código?

Respuesta

55

¿Has probado esto?

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

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

+1

Oh bien que realmente fue estúpido de mi parte. Por supuesto, funciona :) –

+0

no funciona: TypeError: ufunc 'bitwise_or' no es compatible con los tipos de entrada, y las entradas no se pueden forzar de forma segura a los tipos admitidos de acuerdo con la regla de conversión '' seguro '' – Mehdi

+4

Don no olvides poner correctamente las expresiones en corchetes – gota

13

Si tiene comparaciones solo en booleanos, como en su ejemplo, puede usar el operador O bit | según lo sugerido por Jcollado. Pero ten cuidado, esto puede darte resultados extraños si alguna vez utilizas elementos no booleanos, como mask = (foo < 40) | override. Siempre y cuando override garantizado sea False, True, 1 o 0, está usted bien.

Más general es el uso de los operadores del conjunto de comparación de numpy, np.any y np.all. Este fragmento de código devuelve todos los valores entre 35 y 45, que están a 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 es tan bonito como con |, pero mejor que el código en su pregunta.

+0

¡Es un punto flotante! –

+0

Es una buena idea usar 'np.any' y' np.all' específicamente. – htredleaf

1

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

arr = np.array([False, True]) 
~arr 

OUTPUT: array([ True, False], dtype=bool) 

también & qué 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) 

Éstos también trabajan con pandas Serie

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 
+0

De acuerdo con la documentación numpy, parece que '&' lo hace [_bitwise_ y] (https://docs.scipy.org/doc/numpy/reference/generated/numpy.bitwise_and.html#numpy.bitwise_and), no elementwise . – HelloGoodbye

Cuestiones relacionadas