681 votes

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

J'ai du mal à filtrer mon cadre de données de résultats avec un filtre de type or condition. Je veux que mon résultat df pour extraire toutes les colonnes var qui sont supérieures à 0,25 et inférieures à -0,25.

La logique ci-dessous me donne une valeur de vérité ambiguë, mais elle fonctionne lorsque je divise ce filtrage en deux opérations distinctes. Que se passe-t-il ici ? Je ne suis pas sûr de l'endroit où il faut utiliser la méthode suggérée. a.empty(), a.bool(), a.item(),a.any() or a.all() .

result = result[(result['var'] > 0.25) or (result['var'] < -0.25)]

90 votes

Utiliser | au lieu de or

4 votes

Voici une solution de contournement : abs(result['var'])>0.25

5 votes

1voto

Hemanth Kollipara Points 401

Vous devez utiliser les opérateurs binaires | au lieu de or et & au lieu de and dans pandas, vous ne pouvez pas simplement utiliser les instructions bool de python.

Pour un filtrage plus complexe, créez un mask et appliquer le masque sur le dataframe.
Mettez toute votre requête dans le masque et appliquez-le.
Supposons,

mask = (df["col1"]>=df["col2"]) & (stock["col1"]<=df["col2"])
df_new = df[mask]

1voto

Je vais essayer de donner un aperçu des trois méthodes les plus courantes (également mentionnées ci-dessus) :

from timeit import repeat

setup = """
import numpy as np;
import random;
x = np.linspace(0,100);
lb, ub = np.sort([random.random() * 100, random.random() * 100]).tolist()
"""
stmts = 'x[(x > lb) * (x <= ub)]', 'x[(x > lb) & (x <= ub)]', 'x[np.logical_and(x > lb, x <= ub)]'

for _ in range(3):
    for stmt in stmts:
        t = min(repeat(stmt, setup, number=100_000))
        print('%.4f' % t, stmt)
    print()

résultat :

0.4808 x[(x > lb) * (x <= ub)]
0.4726 x[(x > lb) & (x <= ub)]
0.4904 x[np.logical_and(x > lb, x <= ub)]

0.4725 x[(x > lb) * (x <= ub)]
0.4806 x[(x > lb) & (x <= ub)]
0.5002 x[np.logical_and(x > lb, x <= ub)]

0.4781 x[(x > lb) * (x <= ub)]
0.4336 x[(x > lb) & (x <= ub)]
0.4974 x[np.logical_and(x > lb, x <= ub)]

Mais, * n'est pas supporté dans la série Panda, et NumPy Array est plus rapide que le data frame de Pandas (environ 1000 fois plus lent, voir le numéro) :

from timeit import repeat

setup = """
import numpy as np;
import random;
import pandas as pd;
x = pd.DataFrame(np.linspace(0,100));
lb, ub = np.sort([random.random() * 100, random.random() * 100]).tolist()
"""
stmts = 'x[(x > lb) & (x <= ub)]', 'x[np.logical_and(x > lb, x <= ub)]'

for _ in range(3):
    for stmt in stmts:
        t = min(repeat(stmt, setup, number=100))
        print('%.4f' % t, stmt)
    print()

résultat :

0.1964 x[(x > lb) & (x <= ub)]
0.1992 x[np.logical_and(x > lb, x <= ub)]

0.2018 x[(x > lb) & (x <= ub)]
0.1838 x[np.logical_and(x > lb, x <= ub)]

0.1871 x[(x > lb) & (x <= ub)]
0.1883 x[np.logical_and(x > lb, x <= ub)]

Note : ajouter une ligne de code x = x.to_numpy() aura besoin d'environ 20 µs.

Pour ceux qui préfèrent %timeit :

import numpy as np
import random
lb, ub = np.sort([random.random() * 100, random.random() * 100]).tolist()
lb, ub
x = pd.DataFrame(np.linspace(0,100))

def asterik(x):
    x = x.to_numpy()
    return x[(x > lb) * (x <= ub)]

def and_symbol(x):
    x = x.to_numpy()
    return x[(x > lb) & (x <= ub)]

def numpy_logical(x):
    x = x.to_numpy()
    return x[np.logical_and(x > lb, x <= ub)]

for i in range(3):
    %timeit asterik(x)
    %timeit and_symbol(x)
    %timeit numpy_logical(x)
    print('\n')

résultat :

23 µs ± 3.62 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
35.6 µs ± 9.53 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
31.3 µs ± 8.9 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

21.4 µs ± 3.35 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
21.9 µs ± 1.02 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
21.7 µs ± 500 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

25.1 µs ± 3.71 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
36.8 µs ± 18.3 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
28.2 µs ± 5.97 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

0voto

iretex Points 45

J'ai rencontré la même erreur et j'ai été bloqué avec un dataframe pyspark pendant quelques jours, J'ai pu le résoudre avec succès en remplissant les valeurs na avec 0 puisque je comparais des valeurs entières provenant de deux champs.

0voto

satinder singh Points 170

Une petite chose, qui m'a fait perdre du temps.

Mettez les conditions (si vous comparez en utilisant " = ", " != ") entre parenthèses, si vous ne le faites pas, vous obtiendrez également cette exception. Cela fonctionnera

df[(some condition) conditional operator (some conditions)]

Cela ne

df[some condition conditional-operator some condition]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X