首页 > 解决方案 > 是否有一个分类编码器允许我指定起点(即不是 0)?或使特定值不受限制?

问题描述

我正在对一些类别进行编码,但我的程序将 0 视为特殊值,因此我不希望使用它。当我对我的数据帧进行编码时,我想出了如何保留 NaN,但它从 0 开始。

我怎样才能避免它?

import pandas as pd
from sklearn.preprocessing import LabelEncoder
import numpy as np

df = pd.DataFrame({'city':    ['London','Paris','Moscow', 'London', 'NYC', np.nan],
                   'size':    ['M',     'M',    'L', np.nan,     'M',    'L'],
                   'quantity':[12,       1,      4, 5, 8, 10 ]})
catgoricalValues=['city','size']

df[catgoricalValues] = df[catgoricalValues].apply(lambda series: pd.Series(
    LabelEncoder().fit_transform(series[series.notnull()]),
    index=series[series.notnull()].index
))
print(df)

这是我的结果:

   city  size  quantity
0   0.0   1.0        12
1   3.0   1.0         1
2   1.0   0.0         4
3   0.0   NaN         5
4   2.0   1.0         8
5   NaN   0.0        10

您可以看到结果中有 0,当我执行 df.fillna(0) 将 NaN 转换为 0 时,这将导致不正确的数据。除了构建自己的编码器之外,我能做些什么吗?

标签: pythonpandasencodingscikit-learn

解决方案


您可以编写自己的编码器以从您喜欢的任何数字开始:

class MyLabelEncoder(LabelEncoder):
    def __init__(self, start=1):
        self.start = start
        
    def transform(self, y):
        return super().transform(y) + self.start
    
    def fit_transform(self, y):
        return super().fit_transform(y) + self.start
    
    def inverse_transform(self, y):
        return super().inverse_transform(y - self.start)

# Usage
encoder = MyLabelEncoder()
a = ['London','Paris','Moscow', 'London', 'NYC']
b = encoder.fit_transform(a)
c = encoder.inverse_transform(b)

# The encoded values start at 1
print(b) # array([1, 4, 2, 1, 3], dtype=int64)

# You can get back the original values
assert all(a == c)

推荐阅读