用 pd.categorical 显式定义 categories 和 ordered 参数最稳妥,可精准控制分类顺序、避免 get_dummies 或模型训练时特征错位;labelencoder 仅适用于 target,特征编码须用 ordinalencoder 并配合预排序。

用 pd.Categorical 手动定义分类顺序最稳妥
直接用 pd.Categorical 构造器,能明确控制类别顺序和是否包含缺失值,避免后续 get_dummies 或模型训练时因隐式排序导致特征错位。常见错误是误以为 astype('category') 就够了——它只做类型转换,不指定顺序,而很多下游操作(如 cat.codes、get_dummies(drop_first=True))都依赖顺序。
实操建议:
- 显式传入
categories参数,例如:pd.Categorical(df['col'], categories=['low', 'mid', 'high'], ordered=True) - 若原始列含未声明的值,默认转为
NaN,可加ordered=False放宽限制,或先用df['col'].unique()检查取值范围 - 注意:
pd.Categorical返回的是 Categorical 对象,不是 Series;要赋回列需写成df['col'] = pd.Categorical(...)
get_dummies 生成独热编码时如何控制 dummy 变量顺序
get_dummies 默认按字母序排列列名,但实际建模中常需按业务逻辑(如“低→中→高”)生成列顺序,否则 drop_first=True 可能删掉本该保留的基准类。
实操建议:
- 先用
pd.Categorical设定好有序分类,再传给get_dummies,它会尊重categories顺序生成列名 - 避免对原始字符串列直接调用
get_dummies后再重排列——列名会变成col_low、col_mid等,手动重排易出错 - 若只需数值编码(非独热),直接取
df['col'].cat.codes更轻量,但注意-1表示缺失值
用 LabelEncoder 还是 OrdinalEncoder?别混用
Scikit-learn 的 LabelEncoder 专为单列 target 设计,**不能用于多列特征编码**;误用会导致 fit/transform 不一致,尤其在 Pipeline 中引发数据泄漏或维度错乱。特征编码请统一用 OrdinalEncoder。
实操建议:
-
OrdinalEncoder输入必须是二维数组,传入 DataFrame 时用df[['col1', 'col2']],不能传单列 Series - 它不感知类别顺序,编码结果仅由首次
fit时遇到的唯一值顺序决定——所以务必先对原始列做pd.Categorical排序,再喂给OrdinalEncoder - 若某列含新类别(未在
fit时出现),transform会报ValueError: y contains previously unseen labels,需设handle_unknown='use_encoded_value'并配unknown_value=-1
保存与加载编码器时最容易丢掉的细节
训练完的 OrdinalEncoder 或自定义 categories 映射,如果只存了编码后数据,没存编码规则,上线推理时遇到新数据会崩。常见做法是 pickle 编码器对象,但要注意:
-
pd.Categorical的categories和ordered属性必须随数据一起持久化,否则读取后.cat.codes会按字典序重排 - 用
joblib保存OrdinalEncoder比pickle更稳妥,尤其含大量类别时 - 更健壮的做法是把
categories导出为 JSON 或 CSV,和模型权重分开管理——这样运维查问题时能直接 human-readable 地核对类别是否一致
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











