Когда я попытался воспроизвести, мне показались две вещи:
Ваш код, похоже, ожидает передачи данных в ваш класс.Но в вашем примере вы прошли серию.Я исправил это, обернув ряд в виде кадра данных, прежде чем передать его вашему классу: col = pd.DataFrame(data1['customer_class'])
.
В методе __init__
вашего класса казалось, что вы намеревались выполнить итерациюсписок имен столбцов, но вместо этого фактически перебирал все ваши столбцы, последовательно за серией.Я исправил это, изменив соответствующую строку на: self.col = col.columns.values
.
Ниже я вставил свои модификации в методы класса __init__
и fit
(мой единственный)модификацией метода transform
было возвращение измененного фрейма данных):
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.preprocessing import LabelEncoder
data1 = pd.DataFrame({'customer_class': ['OM1', np.nan, 'OM1'],
'B': [1,6,9],
'C': [2.0, 1.0, np.nan]})
class LabelEncoderByCol(BaseEstimator, TransformerMixin):
def __init__(self,col):
#List of column names in the DataFrame that should be encoded
self.col = col.columns.values
#Dictionary storing a LabelEncoder for each column
self.le_dic = {}
for el in self.col:
self.le_dic[el] = LabelEncoder()
def fit(self,x,y=None):
#Fill missing values with the string 'NaN'
x = x.fillna('NaN')
for el in self.col:
#Only use the values that are not 'NaN' to fit the Encoder
a = x[el][x[el]!='NaN']
self.le_dic[el].fit(a)
return self
def transform(self,x,y=None):
#Fill missing values with the string 'NaN'
x[self.col] = x[self.col].fillna('NaN')
for el in self.col:
#Only use the values that are not 'NaN' to fit the Encoder
a = x[el][x[el]!='NaN']
#Store an ndarray of the current column
b = x[el].get_values()
#Replace the elements in the ndarray that are not 'NaN'
#using the transformer
b[b!='NaN'] = self.le_dic[el].transform(a)
#Overwrite the column in the DataFrame
x[el]=b
return x
Я могу запустить следующие строки (также слегка измененные по сравнению с вашей первоначальной реализацией) без ошибок:
col = pd.DataFrame(data1['customer_class'])
lenc = LabelEncoderByCol(col)
lenc.fit(x=col,y=None)
Затем я могу получить доступ к классам для столбца customer_class
из вашего примера:
lenc.fit(x=col,y=None).le_dic['customer_class'].classes_
Какие выходные данные:
array(['OM1'], dtype=object)
Наконец, я могу преобразовать столбециспользуя метод класса transform
:
lenc.transform(x=col,y=None)
, который выдает следующее:
customer_class
0 0
1 NaN
2 0