Cependant, je sais que cette question a déjà été posée lorsque j'essaie de faire une déclaration if et que j'obtiens une erreur. J'ai regardé ceci lien, mais n'a pas beaucoup aidé dans mon cas. My dfs est une liste de DataFrames.

J'essaye ce qui suit,

for i in dfs:
    if (i['var1'] < 3.000):
       print(i)

Donne l'erreur suivante:

ValueError: La valeur de vérité d'une série est ambiguë. Utilisez a.empty, a.bool (), a.item (), a.any () ou a.all ().

ET j'ai essayé ce qui suit et j'obtiens la même erreur.

for i,j in enumerate(dfs):
    if (j['var1'] < 3.000):
       print(i)

Mon var1 type de données est float32. Je n'utilise aucun autre opérateur logical et & ou |. Dans le lien ci-dessus, cela semblait être dû à l'utilisation d'opérateurs logiques. Pourquoi ai-je ValueError?

10
i.n.n.m 3 août 2017 à 23:26

2 réponses

Meilleure réponse

Voici une petite démo, qui montre pourquoi cela se produit:

In [131]: df = pd.DataFrame(np.random.randint(0,20,(5,2)), columns=list('AB'))

In [132]: df
Out[132]:
    A   B
0   3  11
1   0  16
2  16   1
3   2  11
4  18  15

In [133]: res = df['A'] > 10

In [134]: res
Out[134]:
0    False
1    False
2     True
3    False
4     True
Name: A, dtype: bool

Lorsque nous essayons de vérifier si une telle série est True - Pandas ne sait pas quoi faire:

In [135]: if res:
     ...:     print(df)
     ...:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
...
skipped
...
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Solutions de contournement:

Nous pouvons décider comment traiter les séries de valeurs booléennes - par exemple, if doit renvoyer True si toutes les valeurs sont True:

In [136]: res.all()
Out[136]: False

Ou lorsque au moins une valeur est True:

In [137]: res.any()
Out[137]: True

In [138]: if res.any():
     ...:     print(df)
     ...:
    A   B
0   3  11
1   0  16
2  16   1
3   2  11
4  18  15
7
MaxU 3 août 2017 à 20:58

Actuellement, vous sélectionnez la série entière à des fins de comparaison. Pour obtenir une valeur individuelle de la série, vous voudrez utiliser quelque chose du genre:

for i in dfs:
if (i['var1'].iloc[0] < 3.000):
   print(i)

Pour comparer chacun des éléments individuels, vous pouvez utiliser la série . iteritems (la documentation est rare sur celui-ci) comme ceci:

for i in dfs:
    for _, v in i['var1'].iteritems():
        if v < 3.000:
            print(v)

La meilleure solution ici dans la plupart des cas est de sélectionner un sous-ensemble de la trame de données à utiliser pour tout ce dont vous avez besoin, comme ceci:

for i in dfs:
    subset = i[i['var1'] < 3.000]
    # do something with the subset

Les performances dans les pandas sont beaucoup plus rapides sur les grandes trames de données lors de l'utilisation d'opérations en série au lieu d'itérer sur des valeurs individuelles. Pour plus de détails, vous pouvez consulter la documentation sur la sélection des pandas.

2
Gasvom 3 août 2017 à 20:46