Sklearn Label Кодирование нескольких столбцов pandas dataframe
Я пытаюсь кодировать несколько столбцов, содержащих категориальные данные ("Yes"
и "No"
) в большом кадре данных панд. Полный блок данных содержит более 400 столбцов, поэтому я ищу способ кодирования всех желаемых столбцов без необходимости их кодирования один за другим. Я использую Scikit-learn LabelEncoder
для кодирования категориальных данных.
Первая часть фрейма данных не должна быть закодирована, однако я ищу способ кодирования всех нужных столбцов, содержащих категориальную дату, непосредственно без разделения и конкатенации фрейма данных.
Чтобы продемонстрировать свой вопрос, я сначала попытался решить его на небольшой части фрейма. Однако застряли в последней части, где данные установлены и преобразованы, и получите значение ValueError: bad input shape (4,3)
. Код, который я запускал:
# 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
Полный отчет об ошибке:
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)
Кто-нибудь знает как это сделать?
Ответы
Ответ 1
В качестве следующего кода вы можете кодировать несколько столбцов, применяя LabelEncoder
к DataFrame. Однако учтите, что мы не можем получить информацию о классах для всех столбцов.
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']
Ответ 2
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 """
Ответ 3
У Scikit-learn есть кое-что для этого: OrdinalEncoder
from sklearn.preprocessing import OrdinalEncoder
data = pd.DataFrame({'A': [1, 2, 3, 4],
'B': ["Yes", "No", "Yes", "Yes"],
'C': ["Yes", "No", "No", "Yes"],
'D': ["No", "Yes", "No", "Yes"]})
oe = OrdinalEncoder()
t_data = oe.fit_transform(data)
print(t_data)
# [[0. 1. 1. 0.]
# [1. 0. 0. 1.]
# [2. 1. 0. 0.]
# [3. 1. 1. 1.]]
Работает прямо из коробки.