标准化应优先用standardscaler以保存参数避免数据泄露,归一化推荐minmaxscaler因其内置除零保护;需预处理缺失值、异常值,并注意dtype转换与索引对齐。

直接用 df.sub(df.mean()).div(df.std()) 或 (df - df.min()) / (df.max() - df.min()) 就能完成多列标准化或归一化,但必须注意缺失值、异常值和训练/测试集一致性——这些地方一错,模型效果就掉档。
标准化:用 df.sub().div() 还是 StandardScaler?
两者都能算 Z-score,但行为差异关键在「是否保存参数」:
-
df.sub(df.mean()).div(df.std())是即时计算,每调用一次都重新算全量mean和std,不保留状态,适合探索性分析或单次批处理 -
StandardScaler的fit_transform()会缓存训练集的mean_和scale_,后续对测试集必须用transform()复用同一组参数,否则数据泄露 - 若 DataFrame 含
NaN,df.mean()默认跳过,但df.std()对全NaN列返回NaN,导致整列变NaN;StandardScaler默认报错,需先用dropna()或fillna()
归一化:MinMaxScaler 比手写公式更稳
手写 (df - df.min()) / (df.max() - df.min()) 看似简洁,但实际容易崩:
- 当某列所有值相等(
max == min),分母为 0,结果全列inf或NaN -
MinMaxScaler内部做了除零保护:遇到常量列时默认设为 0.5(可配feature_range),且支持clip=True防止未来数据超界 - 如果要用 pandas 原生写法,至少加一层判断:
df.apply(lambda x: (x - x.min()) / (x.max() - x.min()) if x.max() != x.min() else 0.5)
多列处理时,别忽略索引对齐和 dtype
标准化/归一化后 DataFrame 的索引和列名不会变,但 dtype 很可能从 int64 变成 float64 ——这本身没问题,但后续若参与 merge 或 groupby,要确认是否影响逻辑:
- 用
df.select_dtypes(include='number')显式限定只处理数值列,避免对时间列或 ID 列误操作 - 如果原数据含
category类型的数值列(如编码后的标签),df.mean()会静默失败,必须先转astype(float) - 归一化后值域是 [0, 1],但浮点精度可能导致极小负数(如 -1e-15),必要时用
np.clip(0, 1)修正
最易被忽略的是:归一化对异常值极度敏感,一个离群的 max 能把整列压缩到接近 0;而标准化虽抗干扰强些,但若训练集标准差极小(比如某特征方差是 1e-8),div() 后数值会爆炸。上线前务必用 describe() 扫一眼缩放后各列的 min/max/std。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











