web-dev-qa-db-fra.com

Filtrage pandas dataframe avec plusieurs colonnes booléennes

J'essaie de filtrer un df en utilisant plusieurs variables booléennes qui font partie du df, mais que je n'ai pas pu faire.

Échantillon de données:

A | B | C | D
John Doe | 45 | True | False
Jane Smith | 32 | False | False
Alan Holmes | 55 | False | True
Eric Lamar | 29 | True | True

Le type pour les colonnes C et D est booléen. Je veux créer un nouveau df (df1) avec uniquement les lignes où C ou D est True. Ça devrait ressembler à ça:

A | B | C | D
John Doe | 45 | True | False
Alan Holmes | 55 | False | True
Eric Lamar | 29 | True | True

J'ai essayé quelque chose comme ceci, qui rencontre des problèmes parce qu'il ne peut pas gérer le type booléen:

df1 = df[(df['C']=='True') or (df['D']=='True')]

Des idées?

17
Maya Harary
In [82]: d
Out[82]:
             A   B      C      D
0     John Doe  45   True  False
1   Jane Smith  32  False  False
2  Alan Holmes  55  False   True
3   Eric Lamar  29   True   True

Solution 1:

In [83]: d.loc[d.C | d.D]
Out[83]:
             A   B      C      D
0     John Doe  45   True  False
2  Alan Holmes  55  False   True
3   Eric Lamar  29   True   True

Solution 2:

In [94]: d[d[['C','D']].any(1)]
Out[94]:
             A   B      C      D
0     John Doe  45   True  False
2  Alan Holmes  55  False   True
3   Eric Lamar  29   True   True

Solution 3:

In [95]: d.query("C or D")
Out[95]:
             A   B      C      D
0     John Doe  45   True  False
2  Alan Holmes  55  False   True
3   Eric Lamar  29   True   True

PS Si vous changez votre solution en:

df[(df['C']==True) | (df['D']==True)]

ça va marcher aussi

Pandas docs - indexation booléenne


pourquoi nous ne devrions PAS utiliser "plainte PEP" df["col_name"] is True au lieu de df["col_name"] == True?

In [11]: df = pd.DataFrame({"col":[True, True, True]})

In [12]: df
Out[12]:
    col
0  True
1  True
2  True

In [13]: df["col"] is True
Out[13]: False               # <----- oops, that's not exactly what we wanted
29
MaxU

Hourra! Plus d'options!

np.where

df[np.where(df.C | df.D, True, False)]

             A   B      C      D
0     John Doe  45   True  False
2  Alan Holmes  55  False   True
3   Eric Lamar  29   True   True  

pd.Series.where sur df.index

df.loc[df.index.where(df.C | df.D).dropna()]

               A   B      C      D
0.0     John Doe  45   True  False
2.0  Alan Holmes  55  False   True
3.0   Eric Lamar  29   True   True

df.select_dtypes

df[df.select_dtypes([bool]).any(1)]   

             A   B      C      D
0     John Doe  45   True  False
2  Alan Holmes  55  False   True
3   Eric Lamar  29   True   True

Abuser np.select

df.iloc[np.select([df.C | df.D], [df.index])].drop_duplicates()

             A   B      C      D
0     John Doe  45   True  False
2  Alan Holmes  55  False   True
3   Eric Lamar  29   True   True
8
cs95

Ou

d[d.eval('C or D')]

Out[1065]:
             A   B      C      D
0     John Doe  45   True  False
2  Alan Holmes  55  False   True
3   Eric Lamar  29   True   True
4
WeNYoBen