web-dev-qa-db-fra.com

Étiquette Sklearn Encodage de plusieurs colonnes pandas dataframe

J'essaie de coder un certain nombre de colonnes contenant des données catégorielles ("Yes" et "No") dans une grande base de données de pandas. La base de données complète contient plus de 400 colonnes. Je cherche donc un moyen de coder toutes les colonnes souhaitées sans les coder une par une. J'utilise Scikit-learn LabelEncoder pour encoder les données catégoriques. 

La première partie de la trame de données ne doit pas nécessairement être codée, mais je cherche une méthode pour coder toutes les colonnes souhaitées contenant une date catégorique directement sans fractionner et concaténer la trame de données.

Pour illustrer ma question, j'ai d'abord essayé de la résoudre sur une petite partie du cadre de données. Restez toutefois bloqué à la dernière partie où les données sont ajustées et transformées et obtenez une ValueError: bad input shape (4,3) Le code tel que j'ai couru:

# Create a simple dataframe resembling large dataframe
    data = pd.DataFrame({'A': [1, 2, 3, 4],
                         'B': ["Yes", "No", "Yes", "Yes"],
                         'C': ["Yes", "No", "No", "Yes"],
                         'D': ["No", "Yes", "No", "Yes"]})


# Import required module
from sklearn.preprocessing import LabelEncoder

# Create an object of the label encoder class
labelencoder = LabelEncoder()

# Apply labelencoder object on columns
labelencoder.fit_transform(data.ix[:, 1:])   # First column does not need to be encoded

Rapport d'erreur complet:

labelencoder.fit_transform(data.ix[:, 1:])
Traceback (most recent call last):

  File "<ipython-input-47-b4986a719976>", line 1, in <module>
    labelencoder.fit_transform(data.ix[:, 1:])

  File "C:\Anaconda\Anaconda3\lib\site-packages\sklearn\preprocessing\label.py", line 129, in fit_transform
    y = column_or_1d(y, warn=True)

  File "C:\Anaconda\Anaconda3\lib\site-packages\sklearn\utils\validation.py", line 562, in column_or_1d
    raise ValueError("bad input shape {0}".format(shape))

ValueError: bad input shape (4, 3)

Est-ce que quelqu'un sait comment faire ça? 

5
HelloBlob

En tant que code suivant, vous pouvez coder plusieurs colonnes en appliquant LabelEncoder à DataFrame. Toutefois, veuillez noter que nous ne pouvons pas obtenir les informations sur les classes pour toutes les colonnes.

import pandas as pd
from sklearn.preprocessing import LabelEncoder

df = pd.DataFrame({'A': [1, 2, 3, 4],
                   'B': ["Yes", "No", "Yes", "Yes"],
                   'C': ["Yes", "No", "No", "Yes"],
                   'D': ["No", "Yes", "No", "Yes"]})
print(df)
#    A    B    C    D
# 0  1  Yes  Yes   No
# 1  2   No   No  Yes
# 2  3  Yes   No   No
# 3  4  Yes  Yes  Yes

# LabelEncoder
le = LabelEncoder()

# apply "le.fit_transform"
df_encoded = df.apply(le.fit_transform)
print(df_encoded)
#    A  B  C  D
# 0  0  1  1  0
# 1  1  0  0  1
# 2  2  1  0  0
# 3  3  1  1  1

# Note: we cannot obtain the classes information for all columns.
print(le.classes_)
# ['No' 'Yes']
7
Keiku
import pandas as pd
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.preprocessing import LabelBinarizer
# df is the pandas dataframe
class preprocessing (BaseEstimator, TransformerMixin):
      def __init__ (self, df):
         self.datatypes = df.dtypes.astype(str)
         self.catcolumns = []
         self.cat_encoders = []
         self.encoded_df = []

      def fit (self, df, y = None):
          for ix, val in Zip(self.datatypes.index.values, 
          self.datatypes.values):
              if val =='object':
                 self.catcolumns.append(ix)
          fit_objs = [str(i) for i in range(len(self.catcolumns))]
          for encs, name in Zip(fit_objs,self.catcolumns):
              encs = LabelBinarizer()
              encs.fit(df[name])
              self.cat_encoders.append((name, encs))
          return self
      def transform (self, df , y = None): 
          for name, encs in self.cat_encoders:
              df_c = encs.transform(df[name])
              self.encoded_df.append(pd.DataFrame(df_c))
          self.encoded_df = pd.concat(self.encoded_df, axis = 1, 
          ignore_index 
          = True)
          self.df_num = df.drop(self.catcolumns, axis = 1)
          y = pd.concat([self.df_num, self.encoded_df], axis = 1, 
          ignore_index = True)
          return y        
# use return y.values to use in sci-kit learn pipeline
""" Finds categorical columns in a dataframe and one hot encodes the 
    columns. you can replace labelbinarizer with labelencoder if you 
    require only label encoding. Function returns encoded categorcial data 
    and numerical data as a dataframe """
0
Tobi