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?
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
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"))
Cela fonctionne pour moi:
pandas.factorize( ['B', 'C', 'D', 'B'] )[0]
Sortie:
[0, 1, 2, 0]
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.
@ Quickbeam2k1, voir ci-dessous -
dataset=pd.read_csv('Data2.csv')
np.set_printoptions(threshold=np.nan)
X = dataset.iloc[:,:].values
Utilisation de sklearn
from sklearn.preprocessing import LabelEncoder
labelencoder_X=LabelEncoder()
X[:,0] = labelencoder_X.fit_transform(X[:,0])