You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kaggle警察枪击案数据集Label编码插补后逆转换报错如何解决

问题背景

现有一份可在Kaggle获取的警察枪击案数据集,多列存在缺失值,各列缺失率如下:

UID                0.000000
Name               0.000000
Age                0.018653
Gender             0.000640
Race               0.317429
Date               0.000000
City               0.000320
State              0.000000
Manner_of_death    0.000000
Armed              0.454487
Mental_illness     0.000000
Flee               0.000000
dtype: float64

复制原始DataFrame执行编码、缺失值插补操作后,逆转换还原标签时报错。


原始操作步骤
  1. 对所有分类列执行Label encode,涉及列如下:
Index(['Gender', 'Race', 'City', 'State', 'Manner_of_death', 'Armed',
       'Mental_illness', 'Flee'],
      dtype='object')

对应代码:

le = LabelEncoder()
lpf = {}
for col in lepf.columns:    
    lpf[col] = le.fit_transform(lepf[col])
lpfdf = pd.DataFrame(lpf)
  1. 定位原始数据集pf中的nan值,将lpfdf中对应缺失值的编码替换为np.nan:
    统计各列缺失数代码:
for col in lpfdf:
    print(col,"\n",len(np.where(pf[col].to_frame().isna())[0]))

统计结果:

Gender 8

Race 3965

City 4
State 0
Manner_of_death 0
Armed 5677
Mental_illness 0

Flee 0

以City列为例,定位缺失值对应编码后,统一将各列缺失值编码替换为np.nan:

"""
Gender: 2,
Race: 6,
City: 3327,
Armed: 59
"""
lpfdf["Gender"] = lpfdf["Gender"].replace(2, np.nan)
lpfdf["Race"] = lpfdf["Race"].replace(6, np.nan)
lpfdf["City"] = lpfdf["City"].replace(3327, np.nan)
lpfdf["Armed"] = lpfdf["Armed"].replace(59, np.nan)
  1. 实例化IterativeImputer执行插补,取整后生成新DataFrame:
itimp = IterativeImputer()
iilpf = itimp.fit_transform(lpfdf)
itimplpf = pd.DataFrame(np.round(iilpf), columns = lepf.columns)

报错信息

逆转换还原原标签时触发ValueError:

for col in lpfdf:    
    le.inverse_transform(itimplpf[col].astype(int))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-191-fbdde4bb4781> in <module>
      1 for col in lpfdf:
----> 2     le.inverse_transform(itimplpf[col].astype(int))

~\anaconda3\lib\site-packages\sklearn\preprocessing\_label.py in inverse_transform(self, y)
    158         diff = np.setdiff1d(y, np.arange(len(self.classes_)))
    159         if len(diff):
--> 160             raise ValueError(
    161                     "y contains previously unseen labels: %s" % str(diff))
    162         y = np.asarray(y)

ValueError: y contains previously unseen labels: [2 3 4 5]

核心问题原因
  1. 全局共用同一个LabelEncoder实例:循环编码所有分类列时仅用了一个le实例反复fit,该实例最终仅保存了最后一列Flee的类别映射关系,逆转换时用Flee的映射规则转换其他列的编码,自然会出现标签不匹配的报错。
  2. 插补结果存在超出原始编码范围的数值:IterativeImputer输出的是连续值,取整后可能生成原始分类列不存在的编码值(比如Gender列原始有效编码只有0、1,插补后可能出现2、3等不存在的取值),逆转换时无法匹配到对应标签。

解决方法

步骤1:为每列单独存储LabelEncoder实例

编码时每个分类列单独实例化LabelEncoder,保存对应列的映射关系,避免相互覆盖,同时可直接保留空值,省略后续手动替换NaN的操作:

le_dict = {}
lpf = {}
for col in lepf.columns:
    # 每列单独初始化编码器
    le = LabelEncoder()
    # 仅编码非空值,空值直接保留
    non_na_mask = lepf[col].notna()
    lpf_col = lepf[col].copy()
    lpf_col[non_na_mask] = le.fit_transform(lpf_col[non_na_mask])
    lpf[col] = lpf_col
    # 保存当前列的专属编码器
    le_dict[col] = le
lpfdf = pd.DataFrame(lpf)

步骤2:插补后截断编码范围

插补取整后,将每列的编码值限制在该列原始类别对应的编码范围内,避免出现不存在的标签:

itimp = IterativeImputer()
iilpf = itimp.fit_transform(lpfdf)
itimplpf = pd.DataFrame(np.round(iilpf), columns = lepf.columns)

# 对每列做范围截断
for col in itimplpf.columns:
    max_valid_label = len(le_dict[col].classes_) - 1
    itimplpf[col] = itimplpf[col].clip(0, max_valid_label).astype(int)

步骤3:使用对应列的专属编码器逆转换

逆转换时调用该列单独保存的编码器,不要用全局的le实例:

for col in itimplpf.columns:
    itimplpf[col] = le_dict[col].inverse_transform(itimplpf[col])

内容的提问来源于stack exchange,提问作者Mario Aguilar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 00:30:03