【问题标题】:LabelEncoding DataFrame string columnsLabelEncoding DataFrame 字符串列
【发布时间】:2018-08-26 09:21:48
【问题描述】:

我有一个带有浮点数、字符串和可以解释为日期的字符串的 DataFrame。

Label encoding across multiple columns in scikit-learn

from sklearn.base import BaseEstimator, TransformerMixin
class DataFrameSelector(BaseException, TransformerMixin):
    def __init__(self, attribute_names):
        self.attribute_names = attribute_names
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        return X[self.attribute_names].values

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)

num_attributes = ["a", "b", "c"]
num_attributes = list(df_num_median)
str_attributes = list(df_str_only)

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

num_pipeline = Pipeline([
    ('selector', DataFrameSelector(num_attributes)), # transforming the Pandas DataFrame into a NumPy array
    ('imputer', Imputer(strategy="median")), # replacing missing values with the median
    ('std_scalar', StandardScaler()), # scaling the features using standardization (subtract mean value, divide by variance)
])

from sklearn.preprocessing import LabelEncoder

str_pipeline = Pipeline([
    ('selector', DataFrameSelector(str_attributes)), # transforming the Pandas DataFrame into a NumPy array 
    ('encoding', MultiColumnLabelEncoder(str_attributes))
])

from sklearn.pipeline import FeatureUnion
full_pipeline = FeatureUnion(transformer_list=[
    ("num_pipeline", num_pipeline),
    #("str_pipeline", str_pipeline) # replaced by line below
    ("str_pipeline", MultiColumnLabelEncoder(str_attributes))
])

df_prepared = full_pipeline.fit_transform(df_combined)

管道的 num_pipeline 部分工作得很好。在 str_pipeline 部分我得到错误

IndexError: 只有整数、切片 (:)、省略号 (...)、 numpy.newaxis (None) 和整数或布尔数组是有效的索引

如果我注释掉 str_pipeline 中的 MultiColumnLabelEncoder,则不会发生这种情况。我还创建了一些代码来在没有管道的情况下在数据集上应用 MultiColumnLabelEncoder,它工作得很好。有任何想法吗?作为附加步骤,我必须为字符串和日期字符串创建两个单独的管道。

编辑:添加 DataFrameSelector 类

【问题讨论】:

  • @VivekKumar 似乎解决了,但我重新运行了整个过程,但出现错误;看看我对你的回答的评论
  • 您的问题现在解决了吗?你检查数据了吗?

标签: python scikit-learn sklearn-pandas


【解决方案1】:

问题不在于MultiColumnLabelEncoder,而在于管道中它上面的DataFrameSelector

你正在这样做:

str_pipeline = Pipeline([
    ('selector', DataFrameSelector(str_attributes)), # transforming the Pandas DataFrame into a NumPy array 
    ('encoding', MultiColumnLabelEncoder(str_attributes))
])

DataFrameSelector 返回数据框的.values 属性,这是一个numpy 数组。所以很明显,当你在MultiColumnLabelEncoder 中这样做时:

...
...
    if self.columns is not None:
        for col in self.columns:
            output[col] = LabelEncoder().fit_transform(output[col])

错误是由output[col] 引发的。由于outputX 的副本,X 是一个 numpy 数组(因为它已被DataFrameSelector 转换为 numpy 数组)并且它没有关于列名的信息。

由于您已经将'str_attributes' 传递给MultiColumnLabelEncoder,因此您不需要在管道中使用DataFrameSelector。只需这样做:

full_pipeline = FeatureUnion(transformer_list=[
    ("num_pipeline", num_pipeline),
    ("str_pipeline", MultiColumnLabelEncoder(str_attributes))
])

我删除了 str_pipeline,因为它现在只有一个转换器(在删除 DataFrameSelector 之后)。

【讨论】:

  • 我重新执行了整个笔记本,我得到了类型错误:'
  • @Alessandro 您能否在问题中添加新错误的堆栈跟踪和您的新代码
  • @Alessandro 看起来数据有问题。检查您发送给MultiColumnLabelEncoder 的数据是全字符串,还是字符串和数字的组合。
猜你喜欢
  • 2020-12-23
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 2013-08-01
  • 2019-10-03
  • 2020-11-10
相关资源
最近更新 更多