pd.get_dummies() 默认对所有类别列完整展开,不设参考组,导致共线性;加 drop_first=true 可删首列避免该问题,并需注意 nan 处理、列名合法性及高基数变量的替代方案。

pd.get_dummies() 为啥会多出一列?
因为默认对所有类别列都做完整独热展开,没留参考组(reference level)。比如 pd.get_dummies(df, columns=['color']) 遇到 ['red', 'blue', 'green'],直接生成三列 color_red、color_blue、color_green,导致共线性——模型训练时可能报 LinAlgError: Singular matrix 或系数不稳定。
实操建议:
- 加参数
drop_first=True:自动删掉每组的第一列,保留color_blue、color_green,把red当隐式基准 - 只对需要的列编码:别用
pd.get_dummies(df)全量展开,尤其当df含数值列或 ID 列时,会把它们也转成 dummy(变成全 1 列) - 注意
NaN:默认会为缺失值单独建一列color_nan,若想忽略缺失,先用df['color'].fillna('unknown')
和 sklearn 的 OneHotEncoder 有啥关键区别?
pd.get_dummies() 是 pandas 的一次性转换工具,适合探索和快速建模;OneHotEncoder 是 sklearn 的拟合-变换范式,必须先 fit() 再 transform(),才能保证训练集/测试集列一致。
常见错误现象:
- 用
pd.get_dummies(train)和pd.get_dummies(test)分别处理,结果列数不一致(比如测试集缺某个类别),后续model.predict()直接报ValueError: X has 5 features, but OneHotEncoder is expecting 6 -
OneHotEncoder(drop='first')在 sklearn 1.0+ 才支持,旧版本只能靠drop='if_binary'或手动后处理 -
pd.get_dummies()不保存编码映射,下次来新数据无法复现相同列名;OneHotEncoder的categories_属性可导出复用
遇到高基数类别(如 user_id 有 10 万种)还能用 get_dummies 吗?
不能。内存爆炸,生成的稀疏矩阵会吃光 RAM,且几乎必然拖垮模型训练速度。
实操建议:
- 先统计频次:
df['user_id'].value_counts().head(10),看是否长尾严重 - 高频 top-N 显式编码,其余归为
other:df['user_id'].where(df['user_id'].isin(top_users), 'other') - 改用目标编码(Target Encoding)或嵌入(Embedding),但注意目标编码要防数据泄露,务必用 group-kfold 或滞后均值
- 确认是否真需独热:很多树模型(XGBoost、LightGBM)原生支持类别列,直接传
categorydtype 更快更稳
为什么 get_dummies 后列名带空格或括号就报错?
因为生成的列名来自原始列名 + 值,若原始列是 'user type' 或 'status (current)',get_dummies 默认拼成 user type_male、status (current)_active,这些名字在 scikit-learn 等库中常被当作非法标识符,引发 ValueError: Invalid parameter 或 AttributeError。
解决办法:
- 预处理列名:
df.columns = df.columns.str.replace(r'[^a-zA-Z0-9_]', '_', regex=True) - 用
prefix_sep控制分隔符:pd.get_dummies(df, prefix_sep='_')避免默认的下划线冲突 - 手动重命名生成列:
dummy_df = pd.get_dummies(...); dummy_df.columns = [c.replace(' ', '_').replace('(', '').replace(')', '') for c in dummy_df.columns]
真正麻烦的是那种“编码完发现列名含不可见字符或 BOM”的情况,建议在读取 CSV 时就加 encoding='utf-8-sig',否则 get_dummies 会默默把乱码塞进列名里,debug 成本远高于预防。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











