2011-12-25 15 views
36

Per esempio mi piacerebbe creare una maschera che maschera gli elementi con valore tra i 40 ei 60:Come eseguire operazioni booleane elemento saggi sugli array NumPy

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

che sembra proprio brutto, non posso scrivere:

(foo < 40) or (foo > 60) 

perché io alla fine 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() 

esiste un modo canonico di fare elemento saggio ope booleano razioni su array numpy che con un bell'aspetto di codice?

risposta

55

Hai provato questo?

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

Nota: il metodo __or__ in un oggetto sovraccarica l'operatore OR (|), non booleana or operatore.

+1

Vabbè che è stato davvero stupido da parte mia. Ovviamente funziona :) –

+0

non funziona: TypeError: ufunc 'bitwise_or' non supportato per i tipi di input e gli input non possono essere forzati in modo sicuro a qualsiasi tipo supportato in base alla regola di cast '' safe '' – Mehdi

+4

Don 'dimentica di parentesi le espressioni correttamente – gota

13

Se si dispone di confronti all'interno di solo booleani, come nell'esempio, è possibile utilizzare l'operatore OR bit a bit | come suggerito da Jcollado. Ma attenzione, questo può darti strani risultati se usi mai non booleani, come mask = (foo < 40) | override. Solo finché il valore override è garantito come False, True, 1 o 0, stai bene.

Più generale è l'uso degli operatori di set di confronti di numpy, np.any e np.all. Questo frammento ripristina tutti i valori tra 35 e 45, che sono meno di 40 o meno di un multiplo di 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]) 

Non bello come con |, ma più bello del codice nella tua domanda.

+0

È un punto vaid! –

+0

È una buona idea usare 'np.any' e' np.all' in modo specifico. – htredleaf

1

Si noti che è possibile utilizzare ~ per la negazione elementwise.

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

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

anche & fa elementwise e

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) 

Questi inoltre lavorare con Panda 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

Secondo la documentazione di numpy, sembra che '&' fa [_bitwise_ e] (https://docs.scipy.org/doc/numpy/reference/generated/numpy.bitwise_and.html#numpy.bitwise_and), non elementwise . – HelloGoodbye