Подтвердить что ты не робот

Обозначение меток на нескольких столбцах в scikit-learn

Я пытаюсь использовать scikit-learn LabelEncoder для кодирования панд DataFrame строковых меток. Поскольку в фрейме данных много (50+) столбцов, я хочу избежать создания объекта LabelEncoder для каждого столбца; Я бы предпочел просто иметь один большой LabelEncoder который работает во всех моих столбцах данных.

Бросок всего DataFrame в LabelEncoder создает LabelEncoder ошибку. Пожалуйста, имейте в виду, что я использую фиктивные данные здесь; на самом деле я имею в виду около 50 столбцов данных, помеченных строками, поэтому мне нужно решение, которое не ссылается ни на один столбец по имени.

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 (последний вызов был последним): файл "", строка 1, в файле "/Users/bbalin/anaconda/lib/python2.7/site-packages/sklearn/preprocessing/label.py", строка 103, в соответствии y = column_or_1d (y, warn = True) Файл "/Users/bbalin/anaconda/lib/python2.7/site-packages/sklearn/utils/validation.py", строка 306, в column_or_1d повышает ValueError ("неверная форма ввода { 0} ". Format (shape)) ValueError: неправильная форма ввода (6, 3)

Есть мысли о том, как обойти эту проблему?

4b9b3361

Ответ 1

Вы можете легко сделать это,

df.apply(LabelEncoder().fit_transform)

EDIT2:

В scikit-learn 0.20 рекомендуемый способ

OneHotEncoder().fit_transform(df)

поскольку OneHotEncoder теперь поддерживает ввод строки. Применение OneHotEncoder только к определенным столбцам возможно с помощью ColumnTransformer.

EDIT:

Так как этот ответ более года назад и вызвал много голосов (включая награду), я, вероятно, должен расширить это.

Для inverse_transform и transform вам нужно немного взломать.

from collections import defaultdict
d = defaultdict(LabelEncoder)

Теперь вы сохраните все столбцы LabelEncoder в качестве словаря.

# 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))

Ответ 2

Как упоминалось larsmans, LabelEncoder() принимает только 1-мерный массив в качестве аргумента. Тем не менее, довольно легко свернуть собственный кодер ярлыков, который работает по нескольким столбцам по вашему выбору и возвращает преобразованный фрейм данных. Мой код здесь частично основан на замечательном сообщении блога Zac Stewart, найденном здесь.

Создание пользовательского кодера предполагает просто создание класса, отвечающего методам fit(), transform() и fit_transform(). В вашем случае хорошим началом может быть что-то вроде этого:

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)

Предположим, что мы хотим закодировать наши два категориальных атрибута (fruit и color), оставив только числовой атрибут weight. Мы могли бы сделать это следующим образом:

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

Что преобразует наш набор данных fruit_data из

enter image description here до

enter image description here

Передавая его, кадр данных, состоящий полностью из категориальных переменных и опускающий параметр columns, приведет к кодированию каждого столбца (который, как я считаю, вы изначально искали):

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

Это преобразует

enter image description here to

enter image description here.

Обратите внимание, что он, вероятно, задохнется, когда попытается кодировать атрибуты, которые уже являются числовыми (добавьте некоторый код для обработки этого, если хотите).

Еще одна приятная особенность в том, что мы можем использовать этот настраиваемый трансформатор в конвейере:

encoding_pipeline = Pipeline([
    ('encoding',MultiColumnLabelEncoder(columns=['fruit','color']))
    # add more pipeline steps as needed
])
encoding_pipeline.fit_transform(fruit_data)

Ответ 3

Нам не нужен LabelEncoder.

Вы можете преобразовать столбцы в категориальные, а затем получить их коды. Я использовал понимание словаря ниже, чтобы применить этот процесс к каждому столбцу и вернуть результат обратно в кадр данных той же формы с одинаковыми индексами и именами столбцов.

>>> 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

Чтобы создать словарь сопоставления, вы можете просто перечислить категории, используя понимание словаря:

>>> {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'}}

Ответ 4

Начиная с scikit-learn 0.20 вы можете использовать sklearn.compose.ColumnTransformer и sklearn.preprocessing.OneHotEncoder:

Если у вас есть только категориальные переменные, OneHotEncoder напрямую:

from sklearn.preprocessing import OneHotEncoder

OneHotEncoder(handle_unknown='ignore').fit_transform(df)

Если у вас есть разнородные функции:

from sklearn.compose import make_column_transformer
from sklearn.preprocessing import RobustScaler
from sklearn.preprocessing import OneHotEncoder

categorical_columns = ['pets', 'owner', 'location']
numerical_columns = ['age', 'weigth', 'height']
column_trans = make_column_transformer(
    (categorical_columns, OneHotEncoder(handle_unknown='ignore'),
    (numerical_columns, RobustScaler())
column_trans.fit_transform(df)

Дополнительные параметры в документации: http://scikit-learn.org/stable/modules/compose.html#columntransformer-for-heterogeneous-data

Ответ 5

это напрямую не отвечает на ваш вопрос (для чего у Натупитулу Джона и Прайс Хардмана есть фантастические ответы)

Однако, для целей нескольких задач классификации и т.д. вы можете использовать

pandas.get_dummies(input_df) 

это может вводить фрейм данных с категориальными данными и возвращать dataframe с двоичными значениями. переменные значения кодируются в имена столбцов в результирующем кадре данных. подробнее

Ответ 6

Предполагая, что вы просто пытаетесь получить объект sklearn.preprocessing.LabelEncoder(), который может использоваться для представления ваших столбцов, все, что вам нужно сделать, это:

le.fit(df.columns)

В приведенном выше коде у вас будет уникальный номер, соответствующий каждому столбцу. Точнее, у вас будет отображение 1:1 от df.columns до le.transform(df.columns.get_values()). Чтобы получить кодировку столбца, просто передайте ее le.transform(...). В качестве примера следующее будет получать кодировку для каждого столбца:

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

Предполагая, что вы хотите создать объект sklearn.preprocessing.LabelEncoder() для всех ярлыков строк, вы можете сделать следующее:

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

В этом случае у вас, скорее всего, есть уникальные ярлыки строк (как показано в вашем вопросе). Чтобы узнать, какие классы создал кодер, вы можете сделать le.classes_. Вы заметите, что это должно иметь те же элементы, что и в set(y for x in df.get_values() for y in x). Еще раз, чтобы преобразовать метку строки в кодированную метку, используйте le.transform(...). В качестве примера, если вы хотите получить метку для первого столбца в массиве df.columns и в первой строке, вы можете сделать это:

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

Вопрос, который у вас был в вашем комментарии, немного сложнее, но может все же выполняться:

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

Вышеприведенный код выполняет следующие действия:

  • Создайте уникальную комбинацию всех пар (столбец, строка)
  • Представляем каждую пару в виде строковой версии кортежа. Это обходное решение для преодоления класса LabelEncoder, не поддерживающего кортежи как имя класса.
  • Устанавливает новые элементы в LabelEncoder.

Теперь использовать эту новую модель немного сложнее. Предполагая, что мы хотим извлечь представление для того же элемента, которое мы рассмотрели в предыдущем примере (первый столбец в df.columns и в первой строке), мы можем сделать это:

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

Помните, что каждый поиск теперь представляет собой строковое представление кортежа, что содержит (столбец, строка).

Ответ 7

Нет, LabelEncoder этого не делает. Он принимает 1-мерные массивы меток классов и создает 1-мерные массивы. Он предназначен для обработки ярлыков классов в задачах классификации, а не произвольных данных, и любая попытка заставить его использовать в других целях потребует кода для преобразования фактической проблемы в проблему, которую он решает (и решение возвращается к исходному пространству).

Ответ 8

Это на полтора года после факта, но я тоже должен был иметь возможность .transform() множественных столбцов данных pandas сразу (и иметь возможность .inverse_transform() их также). Это расширяет превосходное предложение @PriceHardman выше:

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 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

Пример:

Если df и df_copy() являются фреймами типа pandas смешанного типа, вы можете применить столбцы MultiColumnLabelEncoder() к столбцам dtype=object следующим образом:

# 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)

Доступ к отдельным классам столбцов, меткам столбцов и кодовым кодировщикам, используемым для каждого столбца, можно индексировать:

mcle.all_classes_
mcle.all_encoders_
mcle.all_labels_

Ответ 9

Можно сделать все это в pandas напрямую и хорошо подходит для уникальной способности метода replace.

Сначала сделайте словарь словарей, сопоставляющих столбцы и их значения с их новыми значениями замены.

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}}

Так как это всегда будет одно к одному отображению, мы можем инвертировать внутренний словарь, чтобы получить сопоставление новых значений с оригиналом.

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'}}

Теперь мы можем использовать уникальную способность метода replace использовать вложенный список словарей и использовать внешние ключи в качестве столбцов, а внутренние ключи - как значения, которые мы хотели бы заменить.

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

Мы можем легко вернуться к оригиналу, снова связав метод replace

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

Ответ 10

После долгих поисков и экспериментов с некоторыми ответами здесь и в других местах, я думаю, что ваш ответ здесь:

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

Это сохранит имена категорий в столбцах:

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

Ответ 11

Я проверил исходный код (https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/preprocessing/label.py) LabelEncoder. Он был основан на наборе преобразований numpy, одним из которых является np.unique(). И эта функция принимает только 1-й массив ввода. (поправьте меня, если я ошибаюсь).

Очень грубые идеи... сначала определите, для каких столбцов нужен LabelEncoder, а затем переберите каждый столбец.

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

Возвращенный df будет после кодировки, и label_list покажет вам, что все эти значения означают в соответствующем столбце. Это фрагмент из сценария обработки данных, который я написал для работы. Дайте мне знать, если вы думаете, что может быть дальнейшее улучшение.

РЕДАКТИРОВАТЬ: Просто хочу упомянуть здесь, что методы выше работают с фреймом данных, не пропуская лучшее. Не уверен, как он работает, чтобы фрейм данных содержал недостающие данные. (Я имел дело с отсутствующей процедурой перед выполнением вышеуказанных методов)

Ответ 12

если у нас есть один столбец для кодировки меток и его обратное преобразование, легко, как это сделать, когда в 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

Ответ 13

Следуя комментариям, поднятым по решению @PriceHardman, я предлагаю следующую версию класса:

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

Этот класс подходит кодеру на обучающем наборе и использует модифицированную версию при трансформации. Исходную версию кода можно найти здесь.

Ответ 14

Если у вас есть числовые и категориальные данные обоих типов в фрейме данных, вы можете использовать: здесь X - мой фрейм данных, имеющий категориальные и числовые обе переменные

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]])

Примечание: этот метод хорош, если вы не заинтересованы в конвертации их обратно.

Ответ 15

Короткий путь к LabelEncoder() нескольким столбцам с 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])

и вы можете использовать этот le_dict для labelEncode любой другой столбец:

le_dict[col].transform(df_another[col])

Ответ 16

В основном использовал ответ @Alexander, но пришлось внести некоторые изменения -

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])

Затем для повторного использования в будущем вы можете просто сохранить выходные данные в документ json, а когда вам это нужно, вы прочитаете их и используете функцию .map() как я делал выше.

Ответ 17

Проблема заключается в форме данных (pd dataframe), которые вы передаете в функцию подгонки. Вы должны пройти 1-й список.

Ответ 18

import pandas as pd
from sklearn.preprocessing import LabelEncoder

train=pd.read_csv('.../train.csv')

#X=train.loc[:,['waterpoint_type_group','status','waterpoint_type','source_class']].values
# Create a label encoder object 
def MultiLabelEncoder(columnlist,dataframe):
    for i in columnlist:

        labelencoder_X=LabelEncoder()
        dataframe[i]=labelencoder_X.fit_transform(dataframe[i])
columnlist=['waterpoint_type_group','status','waterpoint_type','source_class','source_type']
MultiLabelEncoder(columnlist,train)

Здесь я читаю csv из местоположения, и в функции я передаю список столбцов, которые я хочу пометить, и фрейм данных, который я хочу применить.

Ответ 19

Как насчет этого?

def MultiColumnLabelEncode(choice, columns, X):
    LabelEncoders = []
    if choice == 'encode':
        for i in enumerate(columns):
            LabelEncoders.append(LabelEncoder())
        i=0    
        for cols in columns:
            X[:, cols] = LabelEncoders[i].fit_transform(X[:, cols])
            i += 1
    elif choice == 'decode': 
        for cols in columns:
            X[:, cols] = LabelEncoders[i].inverse_transform(X[:, cols])
            i += 1
    else:
        print('Please select correct parameter "choice". Available parameters: encode/decode')

Это не самый эффективный, однако он работает, и это очень просто.