simpleimputer在sklearn 1.5+中仅识别np.nan和pd.na(pandas≥1.5),跳过非数值列除非指定strategy='most_frequent',需用columntransformer分列处理并统一缺失值标识为np.nan。

SimpleImputer 在 sklearn 1.5+ 中不再默认支持 None 或 pd.NA,只认 np.nan 和 pd.NA(需 pandas ≥ 1.5),但行为有关键变化:它现在会跳过非数值列(如 object 类型)报错,除非显式指定 strategy='most_frequent' 或用 ColumnTransformer 分开处理。
sklearn 1.5+ 的 SimpleImputer 默认只吃 np.nan
新版强制要求输入数据中缺失值必须是浮点型 np.nan(不是字符串 'NaN'、不是 None、也不是旧版 pandas 的 nan 对象)。如果你从 Excel 或 CSV 读入后直接传给 SimpleImputer,大概率会因 dtype 不匹配而报错:
-
ValueError: Input X contains NaN—— 实际是 dtype 为object,内部含字符串或混合类型,SimpleImputer拒绝处理 -
TypeError: A given column is not numeric—— 列是object类型,哪怕里面全是数字加几个np.nan
解决办法不是“先转 float 再填”,而是提前统一清洗 dtype:
- 对数值列:用
df[col] = pd.to_numeric(df[col], errors='coerce')强制转为float64,把非法字符变np.nan - 对类别列:别塞进
SimpleImputer,改用strategy='most_frequent',且确保列 dtype 是category或object(但不能含np.nan以外的空值)
用 ColumnTransformer 分开处理数值和类别列才是正解
sklearn 1.5 明确不鼓励对整张 DataFrame 直接 fit_transform,因为一列 object 就会让整个 SimpleImputer 失败。必须拆开:
- 数值列用
SimpleImputer(strategy='mean')(或'median') - 类别列用
SimpleImputer(strategy='most_frequent'),注意:该策略在 1.5+ 中已支持pd.NA,但不支持None - 组合时必须用
ColumnTransformer,不能靠pd.concat拼接结果,否则列顺序/索引可能错乱
示例关键片段:
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
<p>num_cols = df.select_dtypes(include='number').columns.tolist()
cat_cols = df.select_dtypes(include='object').columns.tolist()</p><p>preprocessor = ColumnTransformer(
transformers=[
('num', SimpleImputer(strategy='median'), num_cols),
('cat', SimpleImputer(strategy='most_frequent'), cat_cols)
],
remainder='passthrough' # 不参与处理的列原样保留
)</p>
pd.NA 和 np.nan 混用会静默失败
新版 pandas(≥1.5)默认用 pd.NA 表示缺失,但 SimpleImputer 在 1.5+ 中对 pd.NA 的支持是“有限兼容”——仅当列 dtype 是 boolean、string 或 Int64 等可空类型时才识别;一旦列是 object,pd.NA 会被当成普通对象,SimpleImputer 视而不见,导致填充无效。
- 检查方式:
df.dtypes看是否真为string而非object;df.isna().sum()和df.isnull().sum()输出不同就说明混用了 - 统一方案:读取时加
pd.read_csv(..., dtype={'col': 'string'}),或后续用df.astype({'col': 'string'})转换 - 最稳做法:全部转成
np.nan,用df = df.replace([pd.NA, None], np.nan),再确保数值列是float
真正麻烦的不是“怎么填”,而是填之前没意识到:同一份数据里 np.nan、pd.NA、None、空字符串、甚至 'NULL' 可能并存,而 SimpleImputer 只对其中一种敏感。不先做 dtype 和缺失标识归一化,后面所有 fit 都是徒劳。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











