simpleimputer默认数值列用mean、类别列用most_frequent,但需先验检查数据类型与实际内容,避免字符串数字混杂报错;fit_transform仅用于训练集,transform用于测试集以防数据泄漏;transform后需手动转回dataframe保列名;其优势在于可持久化填充统计量,但不支持条件填充。

SimpleImputer 填什么值?默认策略容易踩坑
默认用 mean 填数值列、most_frequent 填类别列,但实际中常忽略数据类型混杂问题。比如 object 列里混着数字字符串("1", "2", "missing"),SimpleImputer 会直接报错或静默失效。
- 先用
df.dtypes和df.apply(lambda x: x.unique()[:3])快速扫一遍列的实际内容,别只信 dtype - 数值列若含异常空格或
"nan"字符串,得先用pd.to_numeric(..., errors='coerce')转成float64再填 - 类别列慎用
most_frequent:如果某类占比 51%,填它看似合理,但若该类在测试集几乎不出现,模型泛化会变差
fit 和 transform 顺序错了,训练集测试集就泄漏
必须对训练集调用 fit_transform,再对测试集只调用 transform。直接对测试集也 fit_transform,等于把测试数据的统计量(如均值)泄露进模型。
- 错误写法:
imputer.fit_transform(X_test)—— 这会让模型“看到”测试数据的分布 - 正确流程:先
imputer.fit_transform(X_train),再imputer.transform(X_test) - 如果用
Pipeline,记得把SimpleImputer放在最前面,否则后续步骤(如StandardScaler)可能因 NaN 报错
列名丢了怎么办?transform 后变 numpy array
SimpleImputer.transform() 默认返回 numpy.ndarray,列名和索引全丢。建模时若依赖列名(比如特征重要性分析、后续 pd.get_dummies),这会立刻出问题。
- 加参数
keep_empty_features=True没用,它只控制空列是否保留,不保列名 - 稳妥做法:手动转回 DataFrame,例如
pd.DataFrame(imputer.transform(X), columns=X.columns, index=X.index) - 注意:如果原始
X是pd.Series,transform会升维成二维,得用.ravel()拉平再塞回去
为什么用 SimpleImputer 而不用 df.fillna?
fillna 简单快捷,但无法跨数据集复用填充逻辑。比如上线后新来一条数据,你没法用训练时的均值去填——那个均值没存下来。
-
SimpleImputer的fit过程会把计算出的填充值存在statistics_属性里,可持久化保存(pickle.dump) -
fillna对每列单独操作,遇到高维稀疏数据(如 one-hot 后的 100+ 列)容易漏掉某些列,而SimpleImputer一次性处理整个数组更可控 - 但注意:
SimpleImputer不支持按条件填充(比如“年龄缺失且性别=女时填 28”),这种得退回loc+fillna
imputer.statistics_ 里存的到底是浮点数还是 np.nan——尤其当某列全空,mean 策略会存一个 nan,后续 transform 就静默失败。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











