如何在不将DataFrame转换为数组的情况下实现独热编码?
分类特征编码:保留DataFrame结构且跨数据集编码一致的方案
核心问题
用ColumnTransformer+OneHotEncoder会把DataFrame转成数组,而pd.get_dummies在不同数据集上会因类别差异导致编码结构不一致,没法直接复用。
解决方案1:用sklearn编码器后转回DataFrame
先在训练集上完成编码器拟合,转换后重新封装成DataFrame,同时保留完整列名:
import pandas as pd from sklearn.preprocessing import OneHotEncoder from sklearn.compose import ColumnTransformer # 定义需要编码的分类特征 categorical_features = ['temp_of_extremities', 'peripheral_pulse', 'mucous_membrane'] # 初始化列转换器:指定编码器返回密集数组,可选处理未知类别 ct = ColumnTransformer( transformers=[ ('encoder', OneHotEncoder(sparse_output=False, handle_unknown='ignore'), categorical_features) ], remainder='passthrough' # 保留其他非分类列 ) # 拟合训练集并转换 df_encoded_array = ct.fit_transform(df) # 拼接所有列名:编码后的分类列 + 原非分类列 encoded_cat_columns = ct.named_transformers_['encoder'].get_feature_names_out(categorical_features) non_categorical_columns = [col for col in df.columns if col not in categorical_features] all_columns = list(encoded_cat_columns) + non_categorical_columns # 转回DataFrame结构 df_encoded = pd.DataFrame(df_encoded_array, columns=all_columns)
解决方案2:跨数据集统一编码
处理另一个同特征的数据集(比如测试集)时,必须用训练集拟合好的转换器,这样编码规则和列结构完全一致:
# 转换测试集 df_test_encoded_array = ct.transform(df_test) df_test_encoded = pd.DataFrame(df_test_encoded_array, columns=all_columns)
为什么pd.get_dummies不行?
pd.get_dummies是基于当前数据集的类别生成列:
- 如果测试集缺少训练集里的某个类别,会少对应列
- 如果测试集有训练集没见过的类别,会多对应列
两种情况都会导致数据集结构不匹配,没法用于后续模型训练或预测。
可选优化
- 若要减少冗余列(k个类别生成k-1列),给
OneHotEncoder加参数drop='first' handle_unknown='ignore'可以让编码器忽略测试集里未见过的类别,对应列填0,避免报错
内容的提问来源于stack exchange,提问作者Паша физтех
相关产品推荐
相关产品推荐

