web-dev-qa-db-fra.com

Pandas: convertir les catégories en nombres

Supposons que j'ai un cadre de données avec des pays qui va comme:

cc | temp
US | 37.0
CA | 12.0
US | 35.0
AU | 20.0

Je sais qu'il existe une fonction pd.get_dummies permettant de convertir les pays en "encodage one-hot". Cependant, je souhaite les convertir en index de manière à obtenir cc_index = [1,2,1,3] À la place.

Je suppose qu'il existe un moyen plus rapide que d'utiliser get_dummies avec une clause numpy where, comme indiqué ci-dessous:

[np.where(x) for x in df.cc.get_dummies().values]

C'est un peu plus facile à faire en R en utilisant 'facteurs' donc j'espère que pandas a quelque chose de similaire.

45
sachinruk

Tout d'abord, changez le type de la colonne:

df.cc = pd.Categorical(df.cc)

Les données ont maintenant l’apparence mais sont stockées de manière catégorique. Pour capturer les codes de catégorie:

df['code'] = df.cc.cat.codes

Maintenant vous avez:

   cc  temp  code
0  US  37.0     2
1  CA  12.0     1
2  US  35.0     2
3  AU  20.0     0

Si vous ne souhaitez pas modifier votre DataFrame mais simplement obtenir les codes:

df.cc.astype('category').cat.codes

Ou utilisez la colonne catégorique comme index:

df2 = pd.DataFrame(df.temp)
df2.index = pd.CategoricalIndex(df.cc)
93
John Zwinck

Si vous souhaitez uniquement transformer votre série en identificateurs d'entiers, vous pouvez utiliser pd.factorize .

Notez cette solution, contrairement à pd.Categorical, ne triera pas par ordre alphabétique. Donc, le premier pays sera assigné 0. Si vous souhaitez commencer à partir de 1, vous pouvez ajouter une constante:

df['code'] = pd.factorize(df['cc'])[0] + 1

print(df)

   cc  temp  code
0  US  37.0     1
1  CA  12.0     2
2  US  35.0     1
3  AU  20.0     3

Si vous souhaitez effectuer un tri alphabétique, spécifiez sort=True:

df['code'] = pd.factorize(df['cc'], sort=True)[0] + 1 
15
jpp

Si vous utilisez la bibliothèque sklearn , vous pouvez utiliser LabelEncoder . Comme pd.Categorical, les chaînes d'entrée sont triées par ordre alphabétique avant l'encodage.

from sklearn.preprocessing import LabelEncoder

LE = LabelEncoder()
df['code'] = LE.fit_transform(df['cc'])

print(df)

   cc  temp  code
0  US  37.0     2
1  CA  12.0     1
2  US  35.0     2
3  AU  20.0     0
4
jpp