SimpleImputer必须先fit再transform,因其填充策略(如均值、众数)依赖训练数据统计量;fit计算每列填充值,transform应用该值,跳过fit会触发NotFittedError。

Scikit-learn 不会自动处理缺失值,SimpleImputer 是唯一内置的、推荐用于预处理阶段的填充工具——但它不能直接用在 fit() 之前含 NaN 的数据上,否则会报错。
为什么 SimpleImputer 必须先 fit() 再 transform()
因为填充策略(如均值、众数)依赖训练数据的统计量。fit() 阶段计算每列的填充值(例如 mean 列的均值),transform() 才用这些值替换 NaN。跳过 fit() 直接 transform() 会触发 NotFittedError。
- 对训练集:必须调用
imputer.fit(X_train)→imputer.transform(X_train) - 对测试集:只能调用
imputer.transform(X_test)(复用训练集算出的填充值) - 如果用
fit_transform(X_train),等价于先fit再transform,更简洁
strategy 参数选哪个?看数据类型和分布
strategy 决定每列用什么值填,不是所有策略都适用于所有列:
-
"mean":仅适用于数值型列;若列含异常值,均值会被拉偏,此时改用"median" -
"median":对离群值鲁棒,适合偏态数值分布 -
"most_frequent":适用于分类变量(字符串或整数标签),填出现最多的类别 -
"constant":需配合fill_value参数,比如填"missing"或-999,便于后续模型识别“人工缺失”
错误示例:SimpleImputer(strategy="mean") 作用于含字符串的列,会抛出 ValueError: Cannot use mean strategy with non-numeric data。
立即学习“Python免费学习笔记(深入)”;
如何安全地对混合类型 DataFrame 使用 SimpleImputer
SimpleImputer 默认只处理数值列(object 类型被跳过),但 pandas DataFrame 混合类型很常见。正确做法是分列处理:
- 用
select_dtypes(include=[np.number])提取数值列,单独用strategy="mean"填充 - 用
select_dtypes(include=["object"])提取类别列,单独用strategy="most_frequent"填充 - 最后用
pd.concat()合并结果(注意保持原始列序和索引) - 不要把整个 DataFrame 直接喂给
SimpleImputer,否则非数值列会被静默丢弃或报错
小技巧:如果只想填某几列,传入二维数组切片,例如 X_train[["age", "income"]],避免影响其他列。
Pipeline 中用 SimpleImputer 时的典型陷阱
放进 sklearn.pipeline.Pipeline 很方便,但容易忽略两个关键点:
- 如果 Pipeline 第一步是
SimpleImputer,它内部仍按列独立拟合——所以确保传入的是二维结构(shape = (n_samples, n_features)),一维数组(如X_train[:, 0])会报ValueError: Expected 2D array -
SimpleImputer对稀疏矩阵支持有限:strategy="most_frequent"不支持稀疏输入;"mean"/"median"虽支持,但会转成稠密,可能爆内存 - 用
ColumnTransformer分别处理数值/类别列时,每个SimpleImputer实例必须独立定义,不能共用同一个对象实例
最常被忽略的是:SimpleImputer 的 missing_values 参数默认是 np.nan,如果你的数据用 None、空字符串或特殊码(如 -999)表示缺失,必须显式设置,否则这些值不会被识别为缺失项。


















