我正在熊猫df中的一列上安装scikit learn LabelEncoder。
遇到的字符串映射到整数的顺序是如何确定的?它是确定的吗?
更重要的是,我可以指定这个订单吗?
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
],因为这是字符串在列中出现的顺序。这能做到吗?
它是按排序顺序完成的。在字符串的情况下,它是按字母顺序进行的。没有相关文档,但查看LabelEncoder.transform的源代码,我们可以看到这项工作主要委托给函数numpy.setdiff1d,并提供以下文档:
求两个数组的集合差。
返回排序的,ar1中不在ar2中的唯一值。
(强调我的)。
请注意,由于这没有文档记录,所以它可能是由实现定义的,并且可以在不同版本之间进行更改。可能只是我看到的版本使用了排序顺序,而scikit-learn的其他版本可能会改变这种行为(通过不使用numpy.setdiff1d)。
我也有点惊讶,因为我无法向LabelEncoder
提供订单。单线解决方案可以是这样的:
df['col1_num'] = df['col1'].apply(lambda x: ['first', 'second', 'third', 'fourth'].index(x))
我想为我的一个应用程序指定LabelEncoder的顺序。因为我不想迁移一些代码并使用其他库。我设法实现了一个临时的解决方法。
因为一开始我知道数据集中的类别,所以我创建了虚拟类别,这些类别将按照我想要的特定顺序按字母顺序排序。示例
{
0:ARejected,
1:ZApproved
}
之后,我在数据集上安装了标签编码器。安装后,我更换了标签编码器的类别,以确保在未来它能按照我的要求映射标签。
le=LabelEncoder()
le.fit (X)
le.classes = np.array(['Rejected,'Approved'])
这可能会在特定情况下帮助一些人。这绝对不是一个永久的解决方案,因为当再次安装编码器时,信息可能会丢失。或者如果类别的数量太大。
我建议您使用category_encoders
包中的OrdinalEncoder
。它有一个映射参数,您可以在其中为每个类别设置所需的转换。您可以在文档中阅读更多关于它的信息。
下面是一个实现示例:
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
注意:我建议以这种方式应用编码,因为编码器可能会导致更改其他列的数据类型的问题。