使用pd.get_dummies时训练与测试集列数不一致的解决方法咨询
解决pd.get_dummies()训练集与测试集编码列数不一致的问题
这个问题我之前在处理机器学习数据的时候也碰到过!核心原因就是训练集和测试集的分类变量存在「独有类别」,导致独热编码后的列数不匹配。下面给你几个实用的解决办法,按场景选就行:
1. 合并数据集后编码再拆分(适合小数据集)
这是最直观的方法——先把训练集和测试集合并,统一做独热编码,再拆分回原数据集。这样能保证编码后的列完全一致,缺失的类别会自动填充0。
示例代码:
import pandas as pd # 假设train_df、test_df是你的训练集和测试集 train_df['data_type'] = 'train' test_df['data_type'] = 'test' # 合并两个数据集 combined_df = pd.concat([train_df, test_df], axis=0, ignore_index=True) # 执行独热编码 combined_dummies = pd.get_dummies(combined_df) # 拆分回训练集和测试集 train_dummies = combined_dummies[combined_dummies['data_type_train'] == 1].drop(['data_type_train', 'data_type_test'], axis=1) test_dummies = combined_dummies[combined_dummies['data_type_test'] == 1].drop(['data_type_train', 'data_type_test'], axis=1)
2. 基于训练集的列名对齐测试集(适合大数据集)
如果数据集太大,合并起来内存压力大,可以先对训练集编码,再手动对齐测试集的列:
- 给测试集补上训练集有但它没有的列,值设为0
- 删除测试集有但训练集没有的列(模型没见过这些特征,不能用于预测)
示例代码:
# 先对训练集做独热编码 train_dummies = pd.get_dummies(train_df) # 记录训练集的所有列名 train_columns = train_dummies.columns # 对测试集做独热编码 test_dummies = pd.get_dummies(test_df) # 补全测试集缺失的列,填充0 missing_cols = set(train_columns) - set(test_dummies.columns) for col in missing_cols: test_dummies[col] = 0 # 调整测试集的列顺序与训练集一致,同时删掉测试集独有的列 test_dummies = test_dummies[train_columns]
3. 使用sklearn的OneHotEncoder(推荐机器学习场景)
如果是在机器学习工作流里,更推荐用sklearn的OneHotEncoder,它天生支持“拟合训练集类别→转换测试集”的逻辑,自动保证列数一致,还能忽略测试集出现的训练集没有的类别。
示例代码:
from sklearn.preprocessing import OneHotEncoder import pandas as pd # 初始化编码器:sparse_output=False输出密集矩阵,handle_unknown='ignore'忽略未知类别 encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore') # 只选择分类变量(object或category类型) train_cats = train_df.select_dtypes(include=['object', 'category']) test_cats = test_df.select_dtypes(include=['object', 'category']) # 拟合训练集并转换 train_encoded = encoder.fit_transform(train_cats) train_dummies = pd.DataFrame(train_encoded, columns=encoder.get_feature_names_out()) # 转换测试集 test_encoded = encoder.transform(test_cats) test_dummies = pd.DataFrame(test_encoded, columns=encoder.get_feature_names_out())
这里handle_unknown='ignore'会让测试集中训练集没有的类别对应的编码列全为0,完美解决你的问题。
内容的提问来源于stack exchange,提问作者Zachary Wyman
相关产品推荐
相关产品推荐

