LabelEncoder().fit_transform 给我负值?

Posted

技术标签:

【中文标题】LabelEncoder().fit_transform 给我负值?【英文标题】:LabelEncoder().fit_transform gives me negative values? 【发布时间】:2021-09-13 11:44:30 【问题描述】:

嘿,

我的数据集中的“城市”列中有不同的城市名称。我很想使用 LabelEncoder() 对其进行编码。但是,我得到了非常令人沮丧的负值结果

df['city_enc'] = LabelEncoder().fit_transform(df['City']).astype('int8')

新的 city_enc 列给了我从 -128 到 127 的值。我不明白为什么 LabelEncoder().fit_transform 给了我负值?我希望它会给出从 0 到 (n-1) 的值。谁能给我解释一下?

最好的问候, 兰阮

【问题讨论】:

City 列中有多少个唯一值?如果您有超过 128 个,那么您将获得负值。只需放弃astype('int8') 转换或使用更大的数据类型,例如int16int32 非常感谢,@AlexandruDinu。我已将其更改为 int16。城市名称有 1801 个唯一值。现在效果很好。 【参考方案1】:

您的问题是转换为 int8 类型,它只能将值编码为 -128 到 127。查看此示例:

import pandas as pd
from sklearn.preprocessing import LabelEncoder


df = pd.DataFrame(
    'City': [i for i in range(129)]
)

le = LabelEncoder()

案例一:

df['City_enc1'] = le.fit_transform(df['City'])
print(df['City_enc1'])

>>> 0        0
1        1
2        2
3        3
4        4
      ... 
124    124
125    125
126    126
127    127
128    128
Name: City_enc1, Length: 129, dtype: int64

案例 2:

df['City_enc2'] = le.fit_transform(df['City']).astype('int8')
print(df['City_enc2'])

>>> 0        0
1        1
2        2
3        3
4        4
      ... 
124    124
125    125
126    126
127    127
128   -128
Name: City_enc2, Length: 129, dtype: int8

看到由于第二种情况的转换,LabelEncoder 必须使用负值。

最好完全不转换或选择int16 或更高版本作为替代方案。

【讨论】:

【参考方案2】:

这肯定是因为您尝试对超过 128 (0 ... 127) 个不同的城市进行编码(您可以通过 len(df['City'].unique()) 进行检查)。

当您随后强制转换为 int8 时,您最终会得到负值,以确保所有标签都是不同的。使用int8,您有 256 个不同的值 (-128 ... 127)。例如,如果您将 129 个不同的值编码为 int8,您将使用所有 0 ... 127 个正值,并且将为一项分配标签 -128

一个简单的解决方案是放弃astype('int8') 转换:

df['city_enc'] = LabelEncoder().fit_transform(df['City']) # defaults to 'int64'

【讨论】:

以上是关于LabelEncoder().fit_transform 给我负值?的主要内容,如果未能解决你的问题,请参考以下文章

在 LabelEncoder 中自定义

使用 labelEncoder 时输入形状错误

Scikit learn的AttributeError:'LabelEncoder'对象没有属性'classes_'?

LabelEncoder 在 DataFrame 中指定类

373LabelEncoder 相关

如何使用 scikit LabelEncoder 获取新标签?