Comment puis-je mapper True / False à 1/0 dans un Pandas DataFrame?

134

J'ai une colonne en python pandas DataFrame qui a des valeurs booléennes True / False, mais pour d'autres calculs, j'ai besoin d'une représentation 1/0. Existe-t-il un moyen rapide de faire ça avec pandas / numpy?

Simon Righley
la source
1
Quels autres calculs sont nécessaires?
Jon Clements
Pour parrot @JonClements, pourquoi avez-vous besoin de convertir bool en int pour l'utiliser dans le calcul? bool fonctionne directement avec l'arithmétique (puisqu'il s'agit d'un int en interne).
cs95 le

Réponses:

277

Une façon succincte de convertir une seule colonne de valeurs booléennes en une colonne d'entiers 1 ou 0:

df["somecolumn"] = df["somecolumn"].astype(int)
Utilisateur
la source
4
Le cas du coin est s'il y a des valeurs NaN dans somecolumn. L'utilisation astype(int)échouera alors. Une autre approche, qui convertit Trueen 1.0 et Falseen 0.0 (floats) tout en préservant les valeurs NaN est de faire:df.somecolumn = df.somecolumn.replace({True: 1, False: 0})
DustByte
@DustByte Bonne prise!
Homunculus Reticulli le
@DustByte Ne pourriez-vous pas simplement utiliser astype(float)et obtenir le même résultat?
AMC
65

Multipliez simplement votre Dataframe par 1 (int)

[1]: data = pd.DataFrame([[True, False, True], [False, False, True]])
[2]: print data
          0      1     2
     0   True  False  True
     1   False False  True

[3]: print data*1
         0  1  2
     0   1  0  1
     1   0  0  1
shubhamgoel27
la source
Quels sont les avantages de cette solution?
AMC
44

Trueest 1en Python, et Falseest également 0* :

>>> True == 1
True
>>> False == 0
True

Vous devriez pouvoir effectuer toutes les opérations que vous souhaitez sur eux en les traitant simplement comme s'il s'agissait de nombres, car ce sont des nombres:

>>> issubclass(bool, int)
True
>>> True * 5
5

Donc pour répondre à votre question, aucun travail n'est nécessaire - vous avez déjà ce que vous recherchez.

* L' utilisation Remarque I est comme un mot anglais, pas le mot - clé Python is- Truene sera pas le même objet que tout au hasard 1.

Gareth Latty
la source
1
np.sin(True).dtypeFaites juste attention avec les types de données si vous faites des calculs en virgule flottante: est float16 pour moi.
jorgeca
9
J'ai un dataframe avec une colonne booléenne, et je peux l'appeler df.my_column.mean()très bien (comme vous l'impliquez), mais quand j'essaye: df.groupby("some_other_column").agg({"my_column":"mean"})j'obtiens DataError: No numeric types to aggregate, donc il semble qu'ils ne sont PAS toujours les mêmes. Juste FYI.
dwanderson
Dans la version 24 de pandas (et peut-être plus tôt), vous pouvez très bien agréger les boolcolonnes.
BallpointBen le
1
Il semble que numpy génère également des erreurs avec les types booléens: l' TypeError: numpy boolean subtract, the opérateur -`, est obsolète, utilisez le bitwise_xor, l' ^opérateur ou la fonction logical_xor à la place.
Amadou Kone
Une autre raison pour laquelle ce n'est pas la même chose: df.col1 + df.col2 + df.col3 ne fonctionne pas pour les boolcolonnes comme il le fait pour les intcolonnes
colorlace
22

Vous pouvez également le faire directement sur les cadres

In [104]: df = DataFrame(dict(A = True, B = False),index=range(3))

In [105]: df
Out[105]: 
      A      B
0  True  False
1  True  False
2  True  False

In [106]: df.dtypes
Out[106]: 
A    bool
B    bool
dtype: object

In [107]: df.astype(int)
Out[107]: 
   A  B
0  1  0
1  1  0
2  1  0

In [108]: df.astype(int).dtypes
Out[108]: 
A    int64
B    int64
dtype: object
Jeff
la source
2

Vous pouvez utiliser une transformation pour votre bloc de données:

df = pd.DataFrame(my_data condition)

transformation Vrai / Faux en 1/0

df = df*1
Bruno Benevides
la source
C'est identique à cette solution , publiée 3 ans plus tôt.
AMC
1

Utilisez Series.viewpour convertir un booléen en nombres entiers:

df["somecolumn"] = df["somecolumn"].view('i1')
jezrael
la source