Par exemple, je voudrais créer un masque qui masque les éléments dont la valeur est comprise entre 40 et 60:
foo = np.asanyarray(range(100))
mask = (foo < 40).__or__(foo > 60)
Ce qui a l'air moche, je ne peux pas écrire:
(foo < 40) or (foo > 60)
parce que je me retrouve avec:
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()
Existe-t-il une manière canonique de faire des opérations booléennes par élément sur des tableaux numpy avec un code beau?
Avez-vous essayé cela?
mask = (foo < 40) | (foo > 60)
Noter la __or__
dans un objet surcharge l'opérateur au niveau du bit ou (|
), pas l'opérateur booléen or
.
Si vous avez des comparaisons uniquement dans les booléens, comme dans votre exemple, vous pouvez utiliser l'opérateur au niveau du bit OR |
Comme suggéré par Jcollado. Mais attention, cela peut vous donner des résultats étranges si vous utilisez des non-booléens, comme mask = (foo < 40) | override
. Tant que override
est garanti comme étant False, True, 1 ou 0, ça va.
Plus général est l'utilisation des opérateurs de jeu de comparaison de numpy, np.any
Et np.all
. Cet extrait renvoie toutes les valeurs comprises entre 35 et 45 qui sont inférieures à 40 ou non un multiple 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])
Pas aussi bien qu'avec |
, Mais plus agréable que le code de votre question.
Vous pouvez utiliser les opérations logiques numpy . Dans votre exemple:
np.logical_or(foo < 40, foo > 60)
Notez que vous pouvez utiliser ~
pour la négation élément par élément.
arr = np.array([False, True])
~arr
OUTPUT: array([ True, False], dtype=bool)
Également &
fait élément par élément et
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)
Ceux-ci fonctionnent également avec 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