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

如何使用ColumnTransformer与OrdinalEncoder做特征转换?出现KeyError如何解决?

问题原因和解决方案
  • 核心问题:ColumnTransformer默认输出无列名的numpy数组,OrdinalEncoder无法通过列名找到对应字段
    你使用的OrdinalEncoder(大概率是category_encoders库的实现)依赖输入数据的列名匹配mapping参数里指定的col字段,而ColumnTransformer默认将每个变换器的输出转为numpy数组,传递给下游object_pre管道的数据已经丢失了列名,因此查找Education列时直接触发KeyError。
  • mapping生成逻辑错误,包含了不需要处理的数值列
    你生成mapping的循环语句for i in list(set(X.columns) - set(ord_cols))遍历了所有字段(包括数值列),但object_pre管道只会收到object_cols对应的字符型字段,数值列不会进入编码器的输入,多余的mapping条目也会引发匹配异常。
  • 管道处理逻辑冲突
    你先对所有字符列做OrdinalEncoder编码,后续的OneHotEncoder指定了cols=ord_cols,此时输入已经是编码后的数值,不存在Gender列名,后续也会触发报错。

修复方案

  1. 给ColumnTransformer开启pandas输出,保留列名(scikit-learn 1.2+版本支持):
preprocessor = ColumnTransformer(transformers=[
    ("num_pre", num_pre, num_cols),
    ("object_pre", object_pre, object_cols)
]).set_output(transform="pandas") # 新增该行,输出带列名的DataFrame
  1. 修正mapping生成逻辑,只遍历字符型列:
# 原有Education、Dependents的mapping定义不变
ord_cols = ["Gender"]
# 只处理未单独定义规则的字符型列
processed_obj_cols = ["Education", "Dependents"] + ord_cols
for i in list(set(object_cols) - set(processed_obj_cols)):
    mapping.append({
        "col": i,
        "mapping": {
            "No": 0,
            "Yes": 1
        }
    })
  1. 调整管道顺序,如果确实需要对部分列做独热编码,建议拆分字符列的处理逻辑,避免编码后列名丢失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:48:00