Je viens de découvrir un bogue logique dans mon code qui causait toutes sortes de problèmes. Je faisais par inadvertance un ET au niveau du bit au lieu d'un ET logique .
J'ai changé le code de:
r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]
À:
r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) and (r["dt"] <= enddate))
selected = r[mask]
À ma grande surprise, j'ai reçu le message d'erreur plutôt cryptique:
ValueError: la valeur de vérité d'un tableau avec plusieurs éléments est ambiguë. Utilisez a.any () ou a.all ()
Pourquoi une erreur similaire n'a-t-elle pas été émise lorsque j'utilise une opération au niveau du bit - et comment puis-je résoudre ce problème?
Réponses:
r
est un tableau numpy (rec). Il enr["dt"] >= startdate
va de même pour un tableau (booléen). Pour les tableaux numpy, l'&
opération renvoie l'élément et les deux tableaux booléens.Les développeurs de NumPy ont estimé qu'il n'y avait pas de moyen communément évalué pour évaluer un tableau dans un contexte booléen: cela pourrait signifier
True
si un élément l'estTrue
, ou cela peut signifierTrue
si tous éléments le sontTrue
, ouTrue
si le tableau a une longueur non nulle, pour n'en nommer que trois possibilités.Étant donné que différents utilisateurs peuvent avoir des besoins et des hypothèses différents, les développeurs de NumPy ont refusé de deviner et ont plutôt décidé de déclencher une ValueError chaque fois que l'on essaie d'évaluer un tableau dans un contexte booléen. L'application
and
à deux tableaux numpy entraîne l'évaluation des deux tableaux dans un contexte booléen (en appelant__bool__
en Python3 ou__nonzero__
en Python2).Votre code d'origine
semble correct. Cependant, si vous le souhaitez
and
, au lieu d'a and b
utiliser(a-b).any()
ou(a-b).all()
.la source
np.all
etnp.any
soient capables de court-circuiter, l'argument qui lui est transmis est évalué avantnp.all
ounp.any
a une chance de court-circuiter. Pour faire mieux, actuellement, vous devez écrire du code C / Cython spécialisé similaire à celui-ci .J'ai eu le même problème (c'est-à-dire l'indexation avec plusieurs conditions, ici, il s'agit de trouver des données dans une certaine plage de dates). Le
(a-b).any()
ou(a-b).all()
ne semble pas fonctionner, du moins pour moi.Alternativement, j'ai trouvé une autre solution qui fonctionne parfaitement pour la fonctionnalité souhaitée ( la valeur de vérité d'un tableau avec plusieurs éléments est ambiguë lorsque vous essayez d'indexer un tableau ).
Au lieu d'utiliser le code suggéré ci-dessus, simplement utiliser un
numpy.logical_and(a,b)
fonctionnerait. Ici, vous voudrez peut-être réécrire le code sous la formela source
La raison de l'exception est que les
and
appels implicitementbool
. D'abord sur l'opérande de gauche et (si l'opérande de gauche l'estTrue
) puis sur l'opérande de droite.x and y
Est donc équivalent àbool(x) and bool(y)
.Cependant le
bool
sur unnumpy.ndarray
(s'il contient plus d'un élément) lèvera l'exception que vous avez vue:L'
bool()
appel est en impliciteand
, mais aussiif
,while
,or
, donc l' un des exemples suivants également échouer:Il y a plus de fonctions et d'instructions en Python qui cachent les
bool
appels, par exemple,2 < x < 10
c'est juste une autre façon d'écrire2 < x and x < 10
. Et l'and
appellerabool
:bool(2 < x) and bool(x < 10)
.L' équivalent élément par élément pour
and
serait lanp.logical_and
fonction, de la même manière que vous pourriez utilisernp.logical_or
comme équivalent pouror
.Pour les tableaux booléennes - et les comparaisons aiment
<
,<=
,==
,!=
,>=
et>
sur les tableaux NumPy renvoient des tableaux numpy booléennes - vous pouvez également utiliser les bitwise-sage élément fonctions (et opérateurs):np.bitwise_and
(&
opérateur)et
bitwise_or
(|
opérateur):Une liste complète des fonctions logiques et binaires se trouve dans la documentation NumPy:
la source
si vous travaillez avec
pandas
ce qui a résolu le problème pour moi, c'est que j'essayais de faire des calculs quand j'avais des valeurs NA, la solution était de lancer:df = df.dropna()
Et après cela, le calcul a échoué.
la source
Ce message d'erreur typé s'affiche également
if-statement
lorsqu'une comparaison est effectuée lorsqu'il existe un tableau et par exemple un booléen ou un int. Voir par exemple:Cette clause a un ensemble de données comme tableau et bool est euhm la "porte ouverte" ...
True
ouFalse
.Dans le cas où la fonction est encapsulée dans un,
try-statement
vous recevrezexcept Exception as error:
le message sans son type d'erreur:la source
essayez ceci => numpy.array (r) ou numpy.array (votre variable) suivi de la commande pour comparer ce que vous souhaitez.
la source