L'évaluation de pandas série de valeurs avec des expressions logiques et si-états
Je vais avoir de la difficulté à évaluer les valeurs d'un dictionnaire à l'aide des instructions if.
Donné le dictionnaire suivant, j'ai importé à partir d'un dataframe (dans le cas où c'est important):
>>> pnl[company]
29: Active Credit Date Debit Strike Type
0 1 0 2013-01-08 2.3265 21.15 Put
1 0 0 2012-11-26 40 80 Put
2 0 0 2012-11-26 400 80 Put
J'ai essayé d'évaluer le texte suivant déclaration d'établir la valeur de la dernière valeur de Active
:
if pnl[company].tail(1)['Active']==1:
print 'yay'
Cependant,j'ai été confronté au message d'erreur suivant:
Traceback (most recent call last):
File "<pyshell#69>", line 1, in <module>
if pnl[company].tail(1)['Active']==1:
File "/usr/lib/python2.7/dist-packages/pandas/core/generic.py", line 676, in __nonzero__
.format(self.__class__.__name__))
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
Cela m'a surpris, étant donné que j'ai pu montrer la valeur que j'ai voulu à l'aide de la commande ci-dessus sans l'instruction if:
>>> pnl[company].tail(1)['Active']
30: 2 0
Name: Active, dtype: object
Étant donné que la valeur est clairement zéro et l'indice est de 2, j'ai essayé ce qui suit, pour un bref contrôle de votre site et a constaté que les choses n'étaient pas passe que je l'aurais attendu:
>>> if pnl[company]['Active'][2]==0:
... print 'woo-hoo'
... else:
... print 'doh'
doh
Ma Question est:
1) Ce qui pourrait se passer ici? Je pense que je suis l'incompréhension de dictionnaires sur certains fondamentaux.
2) j'ai remarqué que comme je l'ai apporter toute valeur donnée de ce dictionnaire, le nombre sur la gauche augmente de 1. Que représente t-il? Par exemple:
>>> pnl[company].tail(1)['Active']
31: 2 0
Name: Active, dtype: object
>>> pnl[company].tail(1)['Active']
32: 2 0
Name: Active, dtype: object
>>> pnl[company].tail(1)['Active']
33: 2 0
Name: Active, dtype: object
>>> pnl[company].tail(1)['Active']
34: 2 0
Name: Active, dtype: object
Merci d'avance pour toute aide.
Series
objets.Cela semble être quelque chose de spécifique à la panda de la bibliothèque que vous utilisez. Il semble que les pandas fournit des objets d'une sorte de loi tels que des dictionnaires, mais diffèrent de façon importante. Pour être clair, vous n'êtes pas affaire avec Python habituel dictionnaires ici, mais en utilisant une structure de données fournies par les pandas qui a dictionnaire de la syntaxe.
Vous donner une série n'est pas un dictionnaire, comme telle, elle ne peut pas évaluer votre requête booléenne, comme l'erreur suggèrent que vous devez faire
pnl[company].tail(1)['Active'].any()==1
même si c'est toujours une valeur uniqueQuant à votre deuxième question, êtes-vous confus l'ordinal nombre de sortie? donc, si vous venez à plusieurs reprises ne imprimer "yay" ou print("bravo") (pour python 3) le nombre toujours incrément
Le fait que vous obtenez des erreurs telles que
The truth value of a Series is ambiguous
de l'intérieur les pandas de la bibliothèque de fichiers source.OriginalL'auteur neanderslob | 2014-05-04
Vous devez vous connecter pour publier un commentaire.
Ce que vous yield Pandas objet de Série, et ce ne peut pas être évalué de la manière que vous essayez, même si ce est juste une seule valeur dont vous avez besoin pour changer votre ligne:
Quant à votre deuxième question, voir mon commentaire.
MODIFIER
De commentaires, et un lien vers votre sortie, appelant
any()
correction du message d'erreur, mais vos données sont en fait des chaînes de sorte que la comparaison n'a toujours pas, vous pouvez soit le faire:De faire une comparaison de chaînes de caractères, ou de corriger les données cependant, il a été lu ou générés.
Ou faire:
Pour convertir le
dtype
de la colonne, de sorte que votre comparaison est plus correct.Qui ressemble à une chaîne ne
if pnl[company].tail(1)['Active'].any()=='0'
travail? voulez-vous comme une chaîne de caractères ou un int/float?Le
.any()
renvoie True ou False. Je ne sais pas si la comparaison de la valeur de retour deany
avec 1 est ce que l'OP a véritablement l'intention...Je ne suis pas d'observer que, lorsque j'appelle
df.tail(1)['col'].any()
elle renvoie la valeur, la comparaison du rendement de la volonté d'un Vrai ou FauxCorrigez, cependant vous lire les données dans le premier endroit ou le faire
pnl['Company']['Active'] = pnl['Company']['Active'].astype(int)
OriginalL'auteur
Une Série est une sous-classe de NDFrame. Le
NDFrame.__bool__
méthode soulève toujours un ValueError. Ainsi, en essayant d'évaluer une Série dans un contexte booléen soulève un ValueError, même si la Série a, mais une seule valeur.La raison pour laquelle NDFrames ont aucune valeur booléenne (err, c'est toujours faire un ValueError), c'est parce qu'il y a plus d'un critère que l'on pourrait raisonnablement s'attendre à une NDFrame pour être Vrai. Cela pourrait signifier
.all()
)Series.any()
).empty()
)Depuis un ou l'autre est possible, et depuis les différents utilisateurs ont des attentes différentes, au lieu de simplement choisir un, les développeurs refusent de deviner et, au lieu de demander à l'utilisateur de la NDFrame à rendre explicite ce critère qu'ils souhaitent utiliser.
Le message d'erreur listes les plus susceptibles choix:
Puisque dans votre cas, vous savez la Série peut contenir qu'une seule valeur, vous pouvez utiliser
item
:Concernant votre deuxième question: les nombres sur La gauche semblent être la numérotation des lignes produites par votre interpréteur Python (PyShell?) - mais c'est juste mon avis.
AVERTISSEMENT: sans doute,
signifie que vous souhaitez que la condition est Vraie quand la valeur unique de la Série est égal à 1. Le code
sera le cas si l'dtype de la Série est numérique et la valeur de la Série est n'importe quel nombre autre que 0. Par exemple, si nous prenons
pnl[company].tail(1)['Active']
être égale àpuis
et, par conséquent,
Je pense que
s.item() == 1
plus fidèlement préserve votre sens:(s == 1).any()
également de travailler, mais à l'aide deany
ne pas exprimer votre intention très simplement, puisque vous savez que la Série va contenir qu'une seule valeur.OriginalL'auteur
Votre question n'a rien à voir avec Python dictionnaires, natif ou Python.
C'est sur les pandas de la Série, et les autres réponses vous a donné la syntaxe correcte:
L'interprétation de vos questions dans le sens le plus large, c'est sur la façon
pandas Series
était entassé surNumPy
, et NumPy historiquement, jusqu'à récemment, avait notoirement pauvres de soutien pour les valeurs logiques et les opérateurs. les pandas ne du mieux qu'elle peut avec ce que NumPy fournit. Ayant parfois appeler manuellement numpy fonctions logiques au lieu d'écrire du code arbitraire (Python) les opérateurs est ennuyeux et maladroit et parfois gonfle pandas code. Aussi, vous avez souvent à cette performance (numpy mieux que médiateur et de natif de Python). Mais c'est le prix que nous payons.Il y a beaucoup de limitations, bizarreries et des pièges (exemples ci-dessous) - le meilleur conseil est de se méfier de booléenne, comme un premier de la classe-citoyen dans les pandas en raison de numpy limitations:
les pandas mises en garde et de Pièges - à l'Aide de Si/Vérité des Énoncés avec les Pandas
une performance exemple: Python ~ peut être utilisé à la place de np.invert() - plus lisible mais 3x plus lent ou pour le pire
certains pièges et les limites: dans le code ci-dessous, note que les récentes numpy permet maintenant de valeurs booléennes (représenté en interne comme int) et permet de NAs, mais que, par exemple,
value_counts()
ignore NAs (à comparer avec le R de la table, qui a l'option 'useNA')..
livre de cuisine a été autour d'un moment: pandas-docs.github.io/pandas-docs-travis/cookbook.html
OriginalL'auteur