Opérateur logique pour l'indexation booléenne dans les Pandas

je travaille avec l'index booléen dans Pandas. La question est pourquoi la déclaration:

a[(a['some_column']==some_number) & (a['some_other_column']==some_other_number)]

fonctionne bien tandis que

a[(a['some_column']==some_number) and (a['some_other_column']==some_other_number)]

existe avec erreur?

exemple:

a=pd.DataFrame({'x':[1,1],'y':[10,20]})

In: a[(a['x']==1)&(a['y']==10)]
Out:    x   y
     0  1  10

In: a[(a['x']==1) and (a['y']==10)]
Out: ValueError: The truth value of an array with more than one element is ambiguous.     Use a.any() or a.all()
59
demandé sur user2988577 2014-01-29 00:04:04

1 réponses

quand vous dites

(a['x']==1) and (a['y']==10)

vous demandez implicitement à Python de convertir (a['x']==1) et (a['y']==10) en valeurs booléennes.

les tableaux NumPy (de longueur supérieure à 1) et les objets Pandas tels que les séries n'ont pas de valeur booléenne -- en d'autres termes, ils soulèvent

ValueError: The truth value of an array is ambiguous. Use a.empty, a.any() or a.all().

lorsqu'il est utilisé comme valeur booléenne. C'est parce que son pas clair quand il devrait être vrai ou faux . Quelque les utilisateurs peuvent supposer qu'ils sont vrais s'ils ont une longueur non nulle, comme une liste Python. D'autres pourraient souhaiter qu'il soit vrai que si tous ses éléments sont vrais. D'autres pourraient vouloir c'est Vrai si tout de ses éléments sont Vrais.

parce qu'il y a tant d'attentes contradictoires, les designers de NumPy et Pandas refusent de deviner, et au lieu de cela soulèvent une erreur de valeur.

à la place, vous devez être explicite, en appelant la méthode empty() , all() ou any() pour indiquer quel comportement vous désirez.

Dans ce cas, cependant, il semble que vous ne souhaitez pas boolean d'évaluation, vous voulez élément-sage logique-et. C'est ce que l'opérateur binaire & exécute:

(a['x']==1) & (a['y']==10)

renvoie un tableau booléen.


Par la façon dont, en tant que alexpmil notes , les parenthèses sont obligatoires puisque & a un plus haut priorité de l'opérateur que == . Sans les parenthèses, a['x']==1 & a['y']==10 serait évalué comme a['x'] == (1 & a['y']) == 10 qui serait à son tour équivalent à la comparaison enchaînée (a['x'] == (1 & a['y'])) and ((1 & a['y']) == 10) . C'est une expression de la forme Series and Series . L'utilisation de and avec deux séries déclencherait à nouveau le même ValueError comme ci-dessus. C'est pourquoi les parenthèses sont obligatoire.

107
répondu unutbu 2017-07-18 19:00:02