Transformez plusieurs colonnes catégorielles

10

Dans mon jeu de données, j'ai deux colonnes catégorielles que je voudrais numéroter. Les deux colonnes contiennent toutes deux des pays, certains se chevauchent (apparaissent dans les deux colonnes). Je voudrais donner le même numéro dans la colonne1 et la colonne2 pour le même pays.

Mes données ressemblent un peu à:

import pandas as pd

d = {'col1': ['NL', 'BE', 'FR', 'BE'], 'col2': ['BE', 'NL', 'ES', 'ES']}
df = pd.DataFrame(data=d)
df

Actuellement, je transforme les données comme:

from sklearn.preprocessing import LabelEncoder
df.apply(LabelEncoder().fit_transform)

Cependant, cela ne fait aucune distinction entre FR et ES. Existe-t-il un autre moyen simple d'arriver à la sortie suivante?

o = {'col1': [2,0,1,0], 'col2': [0,2,4,4]}
output = pd.DataFrame(data=o)
output
Tox
la source

Réponses:

8

Voici une façon

df.stack().astype('category').cat.codes.unstack()
Out[190]: 
   col1  col2
0     3     0
1     0     3
2     2     1
3     0     1

Ou

s=df.stack()
s[:]=s.factorize()[0]
s.unstack()
Out[196]: 
   col1  col2
0     0     1
1     1     0
2     2     3
3     1     3
YOBEN_S
la source
5

Vous pouvez d'abord ajuster LabelEncoder () avec les valeurs uniques de votre trame de données, puis les transformer.

le = LabelEncoder()
le.fit(pd.concat([df.col1, df.col2]).unique()) # or np.unique(df.values.reshape(-1,1))

df.apply(le.transform)
Out[28]: 
   col1  col2
0     3     0
1     0     3
2     2     1
3     0     1
Michael Gardner
la source
2

np.uniqueavec return_invesere. Bien que vous deviez ensuite reconstruire le DataFrame.

pd.DataFrame(np.unique(df, return_inverse=True)[1].reshape(df.shape),
             index=df.index,
             columns=df.columns)

   col1  col2
0     3     0
1     0     3
2     2     1
3     0     1
ALollz
la source