为了账号安全,请及时绑定邮箱和手机立即绑定

在Scikit中跨多个列进行标签编码-学习

/ 猿问

在Scikit中跨多个列进行标签编码-学习

浮云间 2019-07-22 14:47:30

在Scikit中跨多个列进行标签编码-学习

我在试着用LabelEncoder为熊猫编码DataFrame字符串标签。由于dataframe有许多(50+)列,所以我希望避免创建LabelEncoder对象;我宁愿只有一个大的LabelEncoder跨部门工作的对象。我的数据列。

把整个DataFrameLabelEncoder创建以下错误。请记住,我在这里使用的是虚拟数据;实际上,我处理的是大约50列带有字符串标签的数据,因此需要一个不按名称引用任何列的解决方案。

import pandasfrom 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)

追溯(最近一次调用):文件“,第1行,在文件”/Users/bbalin/anaconda/lib/python2.7/site-packages/sklearn/preprocessing/label.py“,第103行,在FIT y=列_或_1D(y,WARN=True)文件”/Users/bbalin/anaconda/lib/python2.7/site-packages/sklearn/utils/validation.py“,行306中,在列_或_1D中提高ValueError(”坏输入形状{0}“。格式(形状)值错误:输入形状错误(6,3)

对如何解决这个问题有什么想法吗?


查看完整描述

3 回答

?
喵喵时光机

不过,你可以很容易地做到这一点,

df.apply(LabelEncoder().fit_transform)

EDIT 2:

在Scikit-学习0.20中,推荐的方法是

OneHotEncoder().fit_transform(df)

因为OneHotEn编码器现在支持字符串输入。仅将OneHotEn编码器应用于某些列是可能的。

编辑:

因为这个答案是一年多以前的,并且引起了很多人的不满(包括赏金),我可能应该进一步扩展这个问题。

对于反变换和变换,你必须做一点点黑客。

from collections import defaultdict
d = defaultdict(LabelEncoder)

现在,您将保留所有列。LabelEncoder作为字典。

# Encoding the variablefit = df.apply(lambda x: d[x.name].fit_transform(x))# Inverse the encodedfit.apply(lambda x: d[x.name].inverse_transform(x))# Using the dictionary to label future datadf.apply(lambda x: d[x.name].transform(x))


查看完整回答
反对 回复 2019-07-22
?
慕姐829404

正如拉斯曼所提到的,LabelEncoder()只接受一个一维数组作为参数。..这就是说,很容易滚动您自己选择的多列的标签编码器,并返回转换后的数据。我这里的代码部分是基于Zac Stewart的优秀博客文章这里.

创建自定义编码器只需创建一个响应于fit()transform(),和fit_transform()方法。在你的例子中,一个好的开端可能是这样的:

import pandas as pdfrom sklearn.preprocessing import LabelEncoderfrom sklearn.pipeline import Pipeline# Create some toy data in a Pandas dataframefruit_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)

假设我们要编码我们的两个分类属性(fruitcolor),同时保留数字属性。weight独自一人。我们可以这样做:

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

这改变了我们fruit_data数据集

传递一个完全由分类变量组成的数据文件,并省略columns参数将导致对每一列进行编码(我认为这是您最初要查找的):

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

这转换

注意,当它试图对已经是数字的属性进行编码时可能会阻塞(如果您愿意的话,可以添加一些代码来处理这个问题)。

这方面的另一个好特性是,我们可以在管道中使用这个自定义转换器:

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


查看完整回答
反对 回复 2019-07-22
?
皈依舞

我们不需要一个标签编码器。

可以将列转换为分类,然后获取它们的代码。我使用下面的字典理解将此过程应用于每一列,并将结果包装回具有相同索引和列名的相同形状的数据。

>>> pd.DataFrame({col: df[col].astype('category').cat.codes for col in df}, index=df.index)
   location  owner  pets0         1      1     01         0      2     12         0      0     03         1      1     24         1      3     15         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'}}


查看完整回答
反对 回复 2019-07-22

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信