Encodage des étiquettes dans plusieurs colonnes de scikit-learn

j'essaie d'utiliser le LabelEncoder de scikit-learn pour coder un pandas DataFrame d'étiquettes de chaîne. Comme la base de données a beaucoup (50+) de colonnes, je veux éviter de créer un LabelEncoder objet pour chaque colonne; je préférerais juste avoir un grand LabelEncoder objets qui fonctionne à travers toutes mes colonnes de données.

lancer le DataFrame entier dans LabelEncoder crée l'erreur ci-dessous. S'il vous plaît gardez à l'esprit que j'utilise des données factices ici; en fait, je traite avec environ 50 colonnes de données marquées chaîne, donc besoin d'une solution qui ne fait référence à aucune colonne par nom.

import pandas
from sklearn import preprocessing 

df = pandas.DataFrame({
    'pets': ['cat', 'dog', 'cat', 'monkey', 'dog', 'dog'], 
    'owner': ['Champ', 'Ron', 'Brick', 'Champ', 'Veronica', 'Ron'], 
    'location': ['San_Diego', 'New_York', 'New_York', 'San_Diego', 'San_Diego', 
                 'New_York']
})

le = preprocessing.LabelEncoder()

le.fit(df)

Traceback (dernier appel en date)): File "", line 1, in Fichier "/Users/bbalin/anaconda/lib/python2.7/site-packages/sklearn/preprocessing/label.py", ligne 103, en forme y = column_or_1d(y, avertir=True) Fichier "/Users/bbalin/anaconda/lib/python2.7/site-packages/sklearn/utils/validation.py", ligne 306, dans colonn_or_1d raise ValueError("mauvaise saisie de la forme {0}".format(forme)) ValueError: la mauvaise qualité des entrées de la forme (6, 3)

des idées pour contourner ce problème?

134
demandé sur Max Ghenis 2014-06-27 22:29:40

16 réponses

, Vous pouvez facilement faire cela,

df.apply(LabelEncoder().fit_transform)

EDIT:

étant donné que cette réponse remonte à plus d'un an, et qu'elle a généré de nombreuses notes positives (y compris une prime), je devrais probablement prolonger cette réponse.

pour inverse_transform et transform, vous devez faire un peu de hack.

from collections import defaultdict
d = defaultdict(LabelEncoder)

avec ceci, vous retenez maintenant toutes les colonnes LabelEncoder comme dictionnaire.

# Encoding the variable
fit = df.apply(lambda x: d[x.name].fit_transform(x))

# Inverse the encoded
fit.apply(lambda x: d[x.name].inverse_transform(x))

# Using the dictionary to label future data
df.apply(lambda x: d[x.name].transform(x))
269
répondu Napitupulu Jon 2016-08-22 10:41:08

comme l'a mentionné larsmans, LabelEncoder() ne prend qu'un tableau 1-d comme argument . Cela dit, il est assez facile de lancer votre propre encodeur d'étiquette qui fonctionne sur plusieurs colonnes de votre choix, et renvoie une dataframe transformée. Mon code ici est basé en partie sur l'excellent billet de blog de Zac Stewart trouvé ici .

la création d'un encodeur personnalisé implique simplement la création d'une classe qui répond à la Méthodes fit() , transform() et fit_transform() . Dans votre cas, un bon début pourrait être quelque chose comme ça:

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from sklearn.pipeline import Pipeline

# Create some toy data in a Pandas dataframe
fruit_data = pd.DataFrame({
    'fruit':  ['apple','orange','pear','orange'],
    'color':  ['red','orange','green','green'],
    'weight': [5,6,3,4]
})

class MultiColumnLabelEncoder:
    def __init__(self,columns = None):
        self.columns = columns # array of column names to encode

    def fit(self,X,y=None):
        return self # not relevant here

    def transform(self,X):
        '''
        Transforms columns of X specified in self.columns using
        LabelEncoder(). If no columns specified, transforms all
        columns in X.
        '''
        output = X.copy()
        if self.columns is not None:
            for col in self.columns:
                output[col] = LabelEncoder().fit_transform(output[col])
        else:
            for colname,col in output.iteritems():
                output[colname] = LabelEncoder().fit_transform(col)
        return output

    def fit_transform(self,X,y=None):
        return self.fit(X,y).transform(X)

supposons que nous voulions encoder nos deux attributs catégoriques ( fruit et color ), tout en laissant l'attribut numérique weight seul. Nous pourrions le faire comme suit:

MultiColumnLabelEncoder(columns = ['fruit','color']).fit_transform(fruit_data)

qui transforme notre ensemble de données fruit_data de

enter image description here à

enter image description here

en lui passant une base de données entièrement constituée de variables catégoriques et en omettant le paramètre columns aura pour résultat que chaque colonne sera encodée (ce que je crois est ce que vous cherchiez à l'origine):

MultiColumnLabelEncoder().fit_transform(fruit_data.drop('weight',axis=1))

ce qui transforme

enter image description here à

enter image description here .

notez qu'il va probablement s'étouffer quand il essaie d'encoder des attributs qui sont déjà numériques (ajouter un certain code pour gérer cela si vous voulez).

une autre caractéristique intéressante à ce sujet est que nous pouvons utiliser ce transformateur personnalisé dans un pipeline:

encoding_pipeline = Pipeline([
    ('encoding',MultiColumnLabelEncoder(columns=['fruit','color']))
    # add more pipeline steps as needed
])
encoding_pipeline.fit_transform(fruit_data)
66
répondu PriceHardman 2015-05-15 19:27:05

nous n'avons pas besoin d'un étiqueteur.

vous pouvez convertir les colonnes en catégories et ensuite obtenir leurs codes. J'ai utilisé une compréhension de dictionnaire ci-dessous pour appliquer ce processus à chaque colonne et envelopper le résultat de nouveau dans une base de données de la même forme avec des indices identiques et des noms de colonne.

>>> pd.DataFrame({col: df[col].astype('category').cat.codes for col in df}, index=df.index)
   location  owner  pets
0         1      1     0
1         0      2     1
2         0      0     0
3         1      1     2
4         1      3     1
5         0      2     1

pour créer un dictionnaire cartographique, vous pouvez simplement énumérer les catégories en utilisant une compréhension du dictionnaire:

>>> {col: {n: cat for n, cat in enumerate(df[col].astype('category').cat.categories)} 
     for col in df}

{'location': {0: 'New_York', 1: 'San_Diego'},
 'owner': {0: 'Brick', 1: 'Champ', 2: 'Ron', 3: 'Veronica'},
 'pets': {0: 'cat', 1: 'dog', 2: 'monkey'}}
10
répondu Alexander 2016-05-04 21:37:16

cela ne répond pas directement à votre question (pour laquelle Naputipulu Jon et PriceHardman ont des réponses fantastiques)

toutefois, pour les besoins de quelques tâches de classification, etc. vous pouvez utiliser

pandas.get_dummies(input_df) 

cela peut entrer dataframe avec des données catégoriques et retourner une dataframe avec des valeurs binaires. les valeurs variables sont encodées dans les noms de colonne dans le dataframe résultant. plus

5
répondu Anurag Priyadarshi 2016-06-24 12:26:42

en supposant que vous essayez simplement d'obtenir un objet sklearn.preprocessing.LabelEncoder() qui peut être utilisé pour représenter vos colonnes, tout ce que vous avez à faire est:

le.fit(df.columns)

Dans le code ci-dessus, vous aurez un numéro unique correspondant à chaque colonne. Plus précisément, vous aurez une carte 1:1 de df.columns à le.transform(df.columns.get_values()) . Pour obtenir l'encodage d'une colonne, passez-le simplement à le.transform(...) . À titre d'exemple, le suivant obtiendra le codage pour chaque colonne:

le.transform(df.columns.get_values())

en supposant que vous voulez créer un objet sklearn.preprocessing.LabelEncoder() pour toutes vos étiquettes de rangée, vous pouvez faire ce qui suit:

le.fit([y for x in df.get_values() for y in x])

dans ce cas, vous avez très probablement des étiquettes de rangée non uniques (comme indiqué dans votre question). Pour voir quelles classes l'encodeur a créé vous pouvez faire le.classes_ . Vous noterez que cela devrait avoir les mêmes éléments que dans set(y for x in df.get_values() for y in x) . Une fois de plus, pour convertir une étiquette de ligne en une étiquette encodée, utilisez le.transform(...) . Par exemple, si vous vous voulez récupérer l'étiquette pour la première colonne dans le tableau df.columns et la première rangée, vous pouvez faire ceci:

le.transform([df.get_value(0, df.columns[0])])

la question que vous aviez dans votre commentaire est un peu plus compliquée, mais peut encore être accompli:

le.fit([str(z) for z in set((x[0], y) for x in df.iteritems() for y in x[1])])

le code ci-dessus fait ce qui suit:

  1. faire une combinaison unique de toutes les paires de (colonne, Rangée)
  2. représente chaque paire comme une chaîne version du n-uplet. Il s'agit d'une solution de contournement pour surmonter la classe LabelEncoder qui ne supporte pas tuples comme nom de classe.
  3. correspond aux nouveaux articles du LabelEncoder .

maintenant, pour utiliser ce nouveau modèle, c'est un peu plus compliqué. En supposant que nous voulons extraire la représentation pour le même article, nous avons cherché dans l'exemple précédent (la première colonne dans df.colonnes et la première ligne), nous pouvons le faire:

le.transform([str((df.columns[0], df.get_value(0, df.columns[0])))])

rappelez-vous que chaque recherche est maintenant une représentation string d'un tuple qui contient le (colonne, ligne).

4
répondu TehTechGuy 2015-03-11 04:43:58

C'est d'un an et demi après le fait, mais moi aussi, nécessaire pour être en mesure de .transform() plusieurs pandas dataframe colonnes à la fois (et être capable de .inverse_transform() ). Ceci développe l'excellente suggestion de @PriceHardman ci-dessus:

class MultiColumnLabelEncoder(LabelEncoder):
    """
    Wraps sklearn LabelEncoder functionality for use on multiple columns of a
    pandas dataframe.

    """
    def __init__(self, columns=None):
        self.columns = columns

    def fit(self, dframe):
        """
        Fit label encoder to pandas columns.

        Access individual column classes via indexig `self.all_classes_`

        Access individual column encoders via indexing
        `self.all_encoders_`
        """
        # if columns are provided, iterate through and get `classes_`
        if self.columns is not None:
            # ndarray to hold LabelEncoder().classes_ for each
            # column; should match the shape of specified `columns`
            self.all_classes_ = np.ndarray(shape=self.columns.shape,
                                           dtype=object)
            self.all_encoders_ = np.ndarray(shape=self.columns.shape,
                                            dtype=object)
            for idx, column in enumerate(self.columns):
                # fit LabelEncoder to get `classes_` for the column
                le = LabelEncoder()
                le.fit(dframe.loc[:, column].values)
                # append the `classes_` to our ndarray container
                self.all_classes_[idx] = (column,
                                          np.array(le.classes_.tolist(),
                                                  dtype=object))
                # append this column's encoder
                self.all_encoders_[idx] = le
        else:
            # no columns specified; assume all are to be encoded
            self.columns = dframe.iloc[:, :].columns
            self.all_classes_ = np.ndarray(shape=self.columns.shape,
                                           dtype=object)
            for idx, column in enumerate(self.columns):
                le = LabelEncoder()
                le.fit(dframe.loc[:, column].values)
                self.all_classes_[idx] = (column,
                                          np.array(le.classes_.tolist(),
                                                  dtype=object))
                self.all_encoders_[idx] = le
        return self

    def fit_transform(self, dframe):
        """
        Fit label encoder and return encoded labels.

        Access individual column classes via indexing
        `self.all_classes_`

        Access individual column encoders via indexing
        `self.all_encoders_`

        Access individual column encoded labels via indexing
        `self.all_labels_`
        """
        # if columns are provided, iterate through and get `classes_`
        if self.columns is not None:
            # ndarray to hold LabelEncoder().classes_ for each
            # column; should match the shape of specified `columns`
            self.all_classes_ = np.ndarray(shape=self.columns.shape,
                                           dtype=object)
            self.all_encoders_ = np.ndarray(shape=self.columns.shape,
                                            dtype=object)
            self.all_labels_ = np.ndarray(shape=self.columns.shape,
                                          dtype=object)
            for idx, column in enumerate(self.columns):
                # instantiate LabelEncoder
                le = LabelEncoder()
                # fit and transform labels in the column
                dframe.loc[:, column] =\
                    le.fit_transform(dframe.loc[:, column].values)
                # append the `classes_` to our ndarray container
                self.all_classes_[idx] = (column,
                                          np.array(le.classes_.tolist(),
                                                  dtype=object))
                self.all_encoders_[idx] = le
                self.all_labels_[idx] = le
        else:
            # no columns specified; assume all are to be encoded
            self.columns = dframe.iloc[:, :].columns
            self.all_classes_ = np.ndarray(shape=self.columns.shape,
                                           dtype=object)
            for idx, column in enumerate(self.columns):
                le = LabelEncoder()
                dframe.loc[:, column] = le.fit_transform(
                        dframe.loc[:, column].values)
                self.all_classes_[idx] = (column,
                                          np.array(le.classes_.tolist(),
                                                  dtype=object))
                self.all_encoders_[idx] = le
        return dframe

    def transform(self, dframe):
        """
        Transform labels to normalized encoding.
        """
        if self.columns is not None:
            for idx, column in enumerate(self.columns):
                dframe.loc[:, column] = self.all_encoders_[
                    idx].transform(dframe.loc[:, column].values)
        else:
            self.columns = dframe.iloc[:, :].columns
            for idx, column in enumerate(self.columns):
                dframe.loc[:, column] = self.all_encoders_[idx]\
                    .transform(dframe.loc[:, column].values)
        return dframe.loc[:, self.columns].values

    def inverse_transform(self, dframe):
        """
        Transform labels back to original encoding.
        """
        if self.columns is not None:
            for idx, column in enumerate(self.columns):
                dframe.loc[:, column] = self.all_encoders_[idx]\
                    .inverse_transform(dframe.loc[:, column].values)
        else:
            self.columns = dframe.iloc[:, :].columns
            for idx, column in enumerate(self.columns):
                dframe.loc[:, column] = self.all_encoders_[idx]\
                    .inverse_transform(dframe.loc[:, column].values)
        return dframe

exemple:

si df et df_copy() sont des images de données de type mixte pandas , vous pouvez appliquer le MultiColumnLabelEncoder() aux colonnes dtype=object de la manière suivante::

# get `object` columns
df_object_columns = df.iloc[:, :].select_dtypes(include=['object']).columns
df_copy_object_columns = df_copy.iloc[:, :].select_dtypes(include=['object'].columns

# instantiate `MultiColumnLabelEncoder`
mcle = MultiColumnLabelEncoder(columns=object_columns)

# fit to `df` data
mcle.fit(df)

# transform the `df` data
mcle.transform(df)

# returns output like below
array([[1, 0, 0, ..., 1, 1, 0],
       [0, 5, 1, ..., 1, 1, 2],
       [1, 1, 1, ..., 1, 1, 2],
       ..., 
       [3, 5, 1, ..., 1, 1, 2],

# transform `df_copy` data
mcle.transform(df_copy)

# returns output like below (assuming the respective columns 
# of `df_copy` contain the same unique values as that particular 
# column in `df`
array([[1, 0, 0, ..., 1, 1, 0],
       [0, 5, 1, ..., 1, 1, 2],
       [1, 1, 1, ..., 1, 1, 2],
       ..., 
       [3, 5, 1, ..., 1, 1, 2],

# inverse `df` data
mcle.inverse_transform(df)

# outputs data like below
array([['August', 'Friday', '2013', ..., 'N', 'N', 'CA'],
       ['April', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['August', 'Monday', '2014', ..., 'N', 'N', 'NJ'],
       ..., 
       ['February', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['April', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['March', 'Tuesday', '2013', ..., 'N', 'N', 'NJ']], dtype=object)

# inverse `df_copy` data
mcle.inverse_transform(df_copy)

# outputs data like below
array([['August', 'Friday', '2013', ..., 'N', 'N', 'CA'],
       ['April', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['August', 'Monday', '2014', ..., 'N', 'N', 'NJ'],
       ..., 
       ['February', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['April', 'Tuesday', '2014', ..., 'N', 'N', 'NJ'],
       ['March', 'Tuesday', '2013', ..., 'N', 'N', 'NJ']], dtype=object)

vous pouvez accéder aux différentes classes de colonnes, étiquettes de colonnes et encodeurs de colonnes utilisés pour ajuster chaque colonne via l'indexation:

mcle.all_classes_

mcle.all_encoders_

mcle.all_labels_

4
répondu Jason Wolosonovich 2016-01-14 20:50:20

Non, LabelEncoder ne pas faire cela. Il prend des tableaux 1-d d'étiquettes de classe et produit des tableaux 1-D. Il est conçu pour traiter les étiquettes de classe dans les problèmes de classification, Pas de données arbitraires, et toute tentative de le forcer dans d'autres utilisations exigera du code pour transformer le problème réel au problème qu'il résout (et la solution de retour à l'espace d'origine).

2
répondu Fred Foo 2014-06-29 10:56:42

si nous avons une seule colonne pour faire l'encodage de l'étiquette et son inverse transformer son facile comment le faire quand il ya plusieurs colonnes en python

def stringtocategory(dataset):
    '''
    @author puja.sharma
    @see The function label encodes the object type columns and gives label      encoded and inverse tranform of the label encoded data
    @param dataset dataframe on whoes column the label encoding has to be done
    @return label encoded and inverse tranform of the label encoded data.
   ''' 
   data_original = dataset[:]
   data_tranformed = dataset[:]
   for y in dataset.columns:
       #check the dtype of the column object type contains strings or chars
       if (dataset[y].dtype == object):
          print("The string type features are  : " + y)
          le = preprocessing.LabelEncoder()
          le.fit(dataset[y].unique())
          #label encoded data
          data_tranformed[y] = le.transform(dataset[y])
          #inverse label transform  data
          data_original[y] = le.inverse_transform(data_tranformed[y])
   return data_tranformed,data_original
1
répondu Puja Sharma 2017-05-05 05:27:30

suite aux commentaires soulevés sur la solution de @PriceHardman je propose la version suivante de la classe:

class LabelEncodingColoumns(BaseEstimator, TransformerMixin):
def __init__(self, cols=None):
    pdu._is_cols_input_valid(cols)
    self.cols = cols
    self.les = {col: LabelEncoder() for col in cols}
    self._is_fitted = False

def transform(self, df, **transform_params):
    """
    Scaling ``cols`` of ``df`` using the fitting

    Parameters
    ----------
    df : DataFrame
        DataFrame to be preprocessed
    """
    if not self._is_fitted:
        raise NotFittedError("Fitting was not preformed")
    pdu._is_cols_subset_of_df_cols(self.cols, df)

    df = df.copy()

    label_enc_dict = {}
    for col in self.cols:
        label_enc_dict[col] = self.les[col].transform(df[col])

    labelenc_cols = pd.DataFrame(label_enc_dict,
        # The index of the resulting DataFrame should be assigned and
        # equal to the one of the original DataFrame. Otherwise, upon
        # concatenation NaNs will be introduced.
        index=df.index
    )

    for col in self.cols:
        df[col] = labelenc_cols[col]
    return df

def fit(self, df, y=None, **fit_params):
    """
    Fitting the preprocessing

    Parameters
    ----------
    df : DataFrame
        Data to use for fitting.
        In many cases, should be ``X_train``.
    """
    pdu._is_cols_subset_of_df_cols(self.cols, df)
    for col in self.cols:
        self.les[col].fit(df[col])
    self._is_fitted = True
    return self

cette classe s'adapte à l'encodeur sur le kit d'entraînement et utilise la version ajustée lors de la transformation. La version initiale du code peut être trouvée ici .

1
répondu Dror 2017-10-12 08:02:10

si vous avez numérique et catégorique les deux types de données dans dataframe Vous pouvez utiliser : voici X est mon dataframe ayant les deux variables catégoriques et numériques

from sklearn import preprocessing
le = preprocessing.LabelEncoder()

for i in range(0,X.shape[1]):
    if X.dtypes[i]=='object':
        X[X.columns[i]] = le.fit_transform(X[X.columns[i]])

Remarque: Cette technique est bonne si vous n'êtes pas intéressé à les convertir en arrière.

1
répondu Vikas Gupta 2018-05-14 20:34:52

j'ai vérifié le code source ( https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/preprocessing/label.py ) de LabelEncoder. Il était fondé sur un ensemble de numpy transformation, qui est np.unique.)( Et cette fonction ne prend que l'entrée du tableau 1-D. (corrigez-moi si je me trompe).

Des idées très grossières... tout d'abord, identifier les colonnes nécessaires LabelEncoder, puis boucle à travers chaque colonne.

def cat_var(df): 
    """Identify categorical features. 

    Parameters
    ----------
    df: original df after missing operations 

    Returns
    -------
    cat_var_df: summary df with col index and col name for all categorical vars
    """
    col_type = df.dtypes
    col_names = list(df)

    cat_var_index = [i for i, x in enumerate(col_type) if x=='object']
    cat_var_name = [x for i, x in enumerate(col_names) if i in cat_var_index]

    cat_var_df = pd.DataFrame({'cat_ind': cat_var_index, 
                               'cat_name': cat_var_name})

    return cat_var_df



from sklearn.preprocessing import LabelEncoder 

def column_encoder(df, cat_var_list):
    """Encoding categorical feature in the dataframe

    Parameters
    ----------
    df: input dataframe 
    cat_var_list: categorical feature index and name, from cat_var function

    Return
    ------
    df: new dataframe where categorical features are encoded
    label_list: classes_ attribute for all encoded features 
    """

    label_list = []
    cat_var_df = cat_var(df)
    cat_list = cat_var_df.loc[:, 'cat_name']

    for index, cat_feature in enumerate(cat_list): 

        le = LabelEncoder()

        le.fit(df.loc[:, cat_feature])    
        label_list.append(list(le.classes_))

        df.loc[:, cat_feature] = le.transform(df.loc[:, cat_feature])

    return df, label_list

Le retour df serait celui après encodage, et label_list vous montrera ce que toutes ces valeurs signifient dans la colonne correspondante. C'est un extrait d'un script de traitement de données que j'ai écrit pour le travail. Dites-moi si vous pensez qu'il pourrait y avoir d'autres améliorations.

MODIFIER: Je veux juste mentionner ici que les méthodes ci-dessus fonctionnent avec la base de données sans manquer le meilleur. Je ne suis pas certain de la façon dont il fonctionne bloc de données contient des données manquantes. (J'ai eu un accord avec la procédure manquante avant d'exécuter les méthodes ci-dessus)

1
répondu willaccc 2018-08-01 21:42:59

il est possible de faire cela directement dans pandas et est bien adapté pour une capacité unique de la méthode replace .

tout d'abord, nous allons faire un dictionnaire de dictionnaires cartographiant les colonnes et leurs valeurs à leurs nouvelles valeurs de remplacement.

transform_dict = {}
for col in df.columns:
    cats = pd.Categorical(df[col]).categories
    d = {}
    for i, cat in enumerate(cats):
        d[cat] = i
    transform_dict[col] = d

transform_dict
{'location': {'New_York': 0, 'San_Diego': 1},
 'owner': {'Brick': 0, 'Champ': 1, 'Ron': 2, 'Veronica': 3},
 'pets': {'cat': 0, 'dog': 1, 'monkey': 2}}

Puisque ce sera toujours une association, nous pouvons inverser l'intérieur dictionnaire pour obtenir une cartographie des nouvelles valeurs d'origine.

inverse_transform_dict = {}
for col, d in transform_dict.items():
    inverse_transform_dict[col] = {v:k for k, v in d.items()}

inverse_transform_dict
{'location': {0: 'New_York', 1: 'San_Diego'},
 'owner': {0: 'Brick', 1: 'Champ', 2: 'Ron', 3: 'Veronica'},
 'pets': {0: 'cat', 1: 'dog', 2: 'monkey'}}

Maintenant, nous pouvons utiliser la capacité unique de la replace méthode pour prendre une liste imbriquée de dictionnaires et d'utiliser l'extérieur des touches comme les colonnes, et l'intérieur des touches comme les valeurs que nous voudrions remplacer.

df.replace(transform_dict)
   location  owner  pets
0         1      1     0
1         0      2     1
2         0      0     0
3         1      1     2
4         1      3     1
5         0      2     1

nous pouvons facilement revenir à l'original en enchaînant à nouveau la méthode replace 151980920"

df.replace(transform_dict).replace(inverse_transform_dict)
    location     owner    pets
0  San_Diego     Champ     cat
1   New_York       Ron     dog
2   New_York     Brick     cat
3  San_Diego     Champ  monkey
4  San_Diego  Veronica     dog
5   New_York       Ron     dog
0
répondu Ted Petrou 2017-11-03 16:49:56

après beaucoup de recherche et d'expérimentation avec quelques réponses ici et ailleurs, je pense que votre réponse est ici :

pd.DataFrame (columns=df.colonne, data=LabelEncoder ().fit_transform(df.valeur.aplatir.))(remodeler(df.de forme))

cela préservera les noms de catégories à travers les colonnes:

import pandas as pd
from sklearn.preprocessing import LabelEncoder

df = pd.DataFrame([['A','B','C','D','E','F','G','I','K','H'],
                   ['A','E','H','F','G','I','K','','',''],
                   ['A','C','I','F','H','G','','','','']], 
                  columns=['A1', 'A2', 'A3','A4', 'A5', 'A6', 'A7', 'A8', 'A9', 'A10'])

pd.DataFrame(columns=df.columns, data=LabelEncoder().fit_transform(df.values.flatten()).reshape(df.shape))

    A1  A2  A3  A4  A5  A6  A7  A8  A9  A10
0   1   2   3   4   5   6   7   9   10  8
1   1   5   8   6   7   9   10  0   0   0
2   1   3   9   6   8   7   0   0   0   0
0
répondu Christopher 2018-06-25 19:23:56

utilisé principalement @Alexander réponse, mais a dû faire quelques changements -

cols_need_mapped = ['col1', 'col2']

mapper = {col: {cat: n for n, cat in enumerate(df[col].astype('category').cat.categories)} 
     for col in df[cols_need_mapped]}

for c in cols_need_mapped :
    df[c] = df[c].map(mapper[c])

alors pour réutiliser dans le futur vous pouvez simplement sauvegarder la sortie dans un document json et quand vous en avez besoin vous la lisez et utilisez la fonction .map() comme je l'ai fait ci-dessus.

0
répondu bbennett36 2018-07-31 19:10:31

le problème est la forme des données (dataframe pd) que vous passez à la fonction fit. Tu dois passer la liste 1d.

0
répondu ali sadr 2018-09-03 20:29:28

un court chemin vers LabelEncoder() colonnes multiples avec un dict() :

from sklearn.preprocessing import LabelEncoder
le_dict = {col: LabelEncoder() for col in columns }
for col in columns:
    le_dict[col].fit_transform(df[col])

et vous pouvez utiliser ce le_dict pour coder n'importe quelle autre colonne:

le_dict[col].transform(df_another[col])
-1
répondu Tom 2017-11-03 04:39:36