web-dev-qa-db-fra.com

Convertir des données catégorielles dans pandas dataframe

J'ai un dataframe avec ce type de données (trop de colonnes):

col1        int64
col2        int64
col3        category
col4        category
col5        category

Les colonnes ressemblent à ceci:

Name: col3, dtype: category
Categories (8, object): [B, C, E, G, H, N, S, W]

Je veux convertir toutes les valeurs des colonnes en nombres entiers comme ceci:

[1, 2, 3, 4, 5, 6, 7, 8]

J'ai résolu ceci pour une colonne par ceci:

dataframe['c'] = pandas.Categorical.from_array(dataframe.col3).codes

Maintenant, j'ai deux colonnes dans mon cadre de données - l'ancien 'col3' et le nouveau 'c' et je dois supprimer les anciennes colonnes.

C'est une mauvaise pratique. Cela fonctionne, mais dans mon cadre de données, de nombreuses colonnes et je ne veux pas le faire manuellement.

Comment cela Pythonic et juste intelligemment?

77
Gilaztdinov Rustam

Premièrement, pour convertir une colonne catégorique en codes numériques, vous pouvez le faire plus facilement avec: dataframe['c'].cat.codes.
De plus, il est possible de sélectionner automatiquement toutes les colonnes avec un type particulier dans une trame de données en utilisant select_dtypes. De cette façon, vous pouvez appliquer l'opération ci-dessus à plusieurs colonnes sélectionnées automatiquement.

Commençons par créer un exemple de cadre de données:

In [75]: df = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})

In [76]: df['col2'] = df['col2'].astype('category')

In [77]: df['col3'] = df['col3'].astype('category')

In [78]: df.dtypes
Out[78]:
col1       int64
col2    category
col3    category
dtype: object

Ensuite, en utilisant select_dtypes pour sélectionner les colonnes, puis en appliquant .cat.codes sur chacune de ces colonnes, vous pouvez obtenir le résultat suivant:

In [80]: cat_columns = df.select_dtypes(['category']).columns

In [81]: cat_columns
Out[81]: Index([u'col2', u'col3'], dtype='object')

In [83]: df[cat_columns] = df[cat_columns].apply(lambda x: x.cat.codes)

In [84]: df
Out[84]:
   col1  col2  col3
0     1     0     0
1     2     1     1
2     3     2     0
3     4     0     1
4     5     1     1
133
joris

Si votre seul souci est de créer une colonne supplémentaire et de la supprimer ultérieurement, utilisez simplement une nouvelle colonne.

dataframe = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})
dataframe.col3 = pd.Categorical.from_array(dataframe.col3).codes

Vous avez terminé. Maintenant que Categorical.from_array est obsolète, utilisez Categorical directement

dataframe.col3 = pd.Categorical(dataframe.col3).codes

Si vous avez également besoin du mappage d’index en libellé, il existe un moyen encore meilleur pour le même

dataframe.col3, mapping_index = pd.Series(dataframe.col3).factorize()

vérifier ci-dessous

print(dataframe)
print(mapping_index.get_loc("c"))
16
Abhishek

Cela fonctionne pour moi:

pandas.factorize( ['B', 'C', 'D', 'B'] )[0]

Sortie:

[0, 1, 2, 0]
15
scottlittle

Ici, plusieurs colonnes doivent être converties. Donc, une approche que j'ai utilisée est ..

for col_name in df.columns:
    if(df[col_name].dtype == 'object'):
        df[col_name]= df[col_name].astype('category')
        df[col_name] = df[col_name].cat.codes

Ceci convertit toutes les colonnes de type chaîne/objet en catégories. Applique ensuite les codes à chaque type de catégorie.

5
shantanu pathak

@ Quickbeam2k1, voir ci-dessous -

dataset=pd.read_csv('Data2.csv')
np.set_printoptions(threshold=np.nan)
X = dataset.iloc[:,:].values

Utilisation de sklearn enter image description here

from sklearn.preprocessing import LabelEncoder
labelencoder_X=LabelEncoder()
X[:,0] = labelencoder_X.fit_transform(X[:,0])
1
Prohadoopian