合并训练测试DataFrame后执行OneHotEncoder触发数值转换错误问题
报错原因
你的疑问本质是混淆了「独热编码的选列范围」和ColumnTransformer的整体处理范围:你只是没有把temp列放到独热编码的目标列里,并不是把它从整个处理流程里排除了。
触发报错的核心逻辑是:
- 你给
ColumnTransformer设置了remainder='passthrough',所有没有被显式指定处理规则的列都会被原封不动保留,temp列没有出现在任何转换规则里,所以会被直接透传到最终的输出结果中。 OneHotEncoder默认输出稀疏矩阵,ColumnTransformer拼接转换后的独热列和透传列时,如果存在稀疏矩阵,要求所有参与拼接的列都必须是可转换为数值的类型,而temp列是存字符串的object类型,'train'/'test'没法转成数值,因此触发报错。
你之前没加temp列的时候,所有透传的列本身就是数值类型,自然不会触发这个问题。
解决方法
你可以选任意一种方案修复:
- 编码前移除temp列(最推荐)
temp列本身只是用来后续拆分数据集的标记,不需要参与编码逻辑。你可以在调用fit_transform之前单独把temp列存下来,输入到ColumnTransformer的df不要带temp列,编码完成后再把temp列拼回去用于拆分:
# 提前存temp列 temp_col = temp_df['temp'] # 输入到ColumnTransformer的df去掉temp列 encode_df = temp_df.drop('temp', axis=1) temp_encoded = ct.fit_transform(encode_df) # 编码完成后把temp列加回去,示例为稀疏矩阵转DataFrame的写法,可根据你的输出格式调整 import pandas as pd encoded_df = pd.DataFrame(temp_encoded.toarray(), columns=ct.get_feature_names_out()) encoded_df['temp'] = temp_col.values # 再做拆分 X = encoded_df[encoded_df['temp'] == 'train'].drop('temp', axis=1) X2 = encoded_df[encoded_df['temp'] == 'test'].drop('temp', axis=1)
- 在ColumnTransformer里显式丢弃temp列
直接在转换规则里指定丢弃temp列,就不会有透传的字符串列了:
ct = ColumnTransformer([('o', OneHotEncoder(), cat_ix), ('drop_temp', 'drop', ['temp'])], remainder='passthrough') temp_df = ct.fit_transform(temp_df) # 拆分时用原temp_df的temp列做索引即可 X = temp_df[temp_df['temp'] == 'train'] X2 = temp_df[temp_df['temp'] == 'test']
- 修改OneHotEncoder输出为稠密矩阵(仅小数据集适用,数据量大时占用内存高)
如果你的数据集很小,可以把OneHotEncoder的输出改成稠密格式,绕过稀疏矩阵的数值校验:
# sklearn 1.2+ 版本用sparse_output,旧版本用sparse参数 ct = ColumnTransformer([('o', OneHotEncoder(sparse_output=False), cat_ix)], remainder='passthrough') # 注意这种方式输出的数组里会包含字符串类型的temp列,后续建模前还是要把temp列删掉
内容的提问来源于stack exchange,提问作者MarkS
相关产品推荐
相关产品推荐

