【问题标题】:LabelEncoder order of fit for a Pandas df适合 Pandas df 的 LabelEncoder 顺序
【发布时间】:2016-12-09 12:17:43
【问题描述】:

我正在将 scikit-learn LabelEncoder 安装在 pandas df 的列上。

如何确定将遇到的字符串映射到整数的顺序?它是确定性的吗?

更重要的是,我可以指定这个顺序吗?

import pandas as pd
from sklearn import preprocessing

df = pd.DataFrame(data=["first", "second", "third", "fourth"], columns=['x'])
le = preprocessing.LabelEncoder()
le.fit(df['x'])
print list(le.classes_)
### this prints ['first', 'fourth', 'second', 'third']
encoded = le.transform(["first", "second", "third", "fourth"]) 
print encoded
### this prints [0 2 3 1]

我希望le.classes_["first", "second", "third", "fourth"],然后encoded[0 1 2 3],因为这是字符串在列中出现的顺序。这个可以吗?

【问题讨论】:

标签: python pandas scikit-learn


【解决方案1】:

它是按排序顺序完成的。在字符串的情况下,它是按字母顺序完成的。没有这方面的文档,但是查看LabelEncoder.transform 的源代码,我们可以看到这项工作主要委托给函数numpy.setdiff1d,具有以下文档:

求两个数组的集合差。

返回 排序的,ar1 中不存在于 ar2 中的唯一值。

(强调我的)。

请注意,由于没有记录,它可能是实现定义的,并且可以在版本之间更改。可能只是我查看的版本使用了排序顺序,而其他版本的 scikit-learn 可能会改变这种行为(不使用 numpy.setdiff1d)。

【讨论】:

  • 至少对于当前版本,它是如何完成的很清楚,它的行为是确定性的。
  • @tkja 但我宁愿不依赖这个。如果它对您的应用程序很重要,不妨自己实现编码。如果您依赖它并且它一直在变化,那么这将是一个非常难以跟踪的错误。
【解决方案2】:

我也有点惊讶我无法向LabelEncoder 提供订单。单行解决方案可以是这样的:

df['col1_num'] = df['col1'].apply(lambda x: ['first', 'second', 'third', 'fourth'].index(x))

【讨论】:

    【解决方案3】:

    我想为我的一个应用程序指定 LabelEncoder 的顺序。因为我不想迁移一些代码并使用其他一些库。我设法为此实施了临时解决方法。

    因为一开始我就知道数据集中的类别,所以我创建了虚拟类别,这些类别将按字母顺序按我想要的特定顺序排序。示例

    {
    0:ARejected,
    1:ZApproved
    }
    

    之后,我在数据集上安装了标签编码器。安装好后,我会替换标签编码器的类,以确保将来它可以按照我的需要映射标签。

    le=LabelEncoder()
    le.fit (X)
    le.classes = np.array(['Rejected,'Approved'])
    

    这可能会在特定情况下对某些人有所帮助。这绝对不是一个永久的解决方案,因为当再次安装编码器时,信息可能会丢失。或者如果类别的数量太大。

    【讨论】:

      【解决方案4】:

      我建议您使用来自category_encoders 包的OrdinalEncoder。它有一个 mapping 参数,您可以在其中为每个类别设置所需的转换。您可以在documentation 中了解更多信息。

      这是一个实现示例:

      from category_encoders import OrdinalEncoder
      
      # Ascending order according to value counts
      keys = df.columnName.value_counts().sort_values(ascending=False).index
      values = list(range(len(keys))) # do np.array()+1 in case you want it to start with 1
      mapping = [{
          'col': 'columnName',
          'mapping': dict(zip(keys, values))
      }]
      oe = OrdinalEncoder(cols=['columnName'], mapping=mapping)
      df.columnName = oe.fit_transform(df).columnName # Read note
      

      注意:我建议以这种方式应用编码,因为编码器可能会导致更改其他列的 dtype 出现问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-20
        • 2019-01-04
        • 2014-10-28
        • 2017-06-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多