NumPy中用np.min和np.max做Min-Max归一化需指定axis=0按列计算极值,用(x-min)/(max-min)公式,并用np.where避免除零;测试集必须复用训练集的min/max以保证一致性。

NumPy怎么用np.min和np.max做Min-Max归一化
直接用 np.min 和 np.max 计算每列(或每行)的极值,再套公式 (x - min) / (max - min) 即可。但要注意:如果某列所有值相等,max - min 会是 0,除零报错 RuntimeWarning: invalid value encountered in true_divide,结果出现 nan。
实操建议:
- 默认按列归一化(即对每个特征独立处理),需显式指定
axis=0,否则np.min(arr)返回的是整个数组最小值,不是每列最小值 - 用
np.where或布尔掩码提前过滤掉max == min的列,避免除零;或者用np.divide配合out和where参数控制 - 如果输入含
nan,np.min/np.max默认返回nan,得改用np.nanmin/np.nanmax
示例(安全版列归一化):
import numpy as np
X = np.array([[1, 2, 3],
[4, 2, 6],
[7, 2, 9]])
<p>col_min = np.min(X, axis=0)
col_max = np.max(X, axis=0)
rng = col_max - col_min</p><h1>防止除零:rng为0的位置设为1,对应归一化后全为0</h1><p>X_norm = (X - col_min) / np.where(rng == 0, 1, rng)</p>
为什么不用sklearn.preprocessing.MinMaxScaler而手写
手写适合快速调试、嵌入轻量脚本、或数据不走 fit/transform 流程(比如实时单样本归一化)。但 MinMaxScaler 能保存 min_ 和 scale_,后续对新数据复用同一缩放参数——手写容易漏掉这点,导致训练/推理不一致。
常见错误现象:
- 训练时用
np.min(X_train)归一化训练集,预测时又用np.min(X_test)单独算,实际应统一用训练集的极值 - 没考虑
feature_range参数,默认是[0, 1],但有时需要映射到[-1, 1],手写就得手动调整公式:2 * (x - min) / (max - min) - 1 -
MinMaxScaler默认只支持二维数组,传入 1Darray会报ValueError: Expected 2D array,而手写对 shape 更灵活
归一化时该用axis=0还是axis=1
绝大多数场景用 axis=0(按列),因为每列表示一个特征(如身高、年龄),归一化目标是让各特征数值范围可比。用 axis=1 是按行归一化,相当于把每个样本自身拉到 [0, 1],这在某些相似度计算或图像 patch 处理中会出现,但不是标准 Min-Max 缩放。
性能与兼容性影响:
-
axis=0是 NumPy 默认广播友好方向,内存连续性好,速度略快 - 若原始数组是 Fortran-order(
order='F'),axis=0操作可能变慢,但一般无需干预 - 混淆
axis容易导致归一化后数据分布异常:比如误用axis=1后,不同特征的量纲差异反而被放大
如何处理测试集或新样本的归一化
必须复用训练集的 min 和 max,不能重新计算。这是最容易被跳过的步骤,尤其在手写流程里。
实操要点:
- 训练阶段存下两个数组:
train_min = np.min(X_train, axis=0)、train_max = np.max(X_train, axis=0) - 预测时直接代入:
X_test_norm = (X_test - train_min) / (train_max - train_min),同样要检查分母为零 - 如果训练集某特征恒定(
train_max == train_min),测试集该特征也应全设为 0(或保持原值),而不是报错中断
这事关模型行为一致性,一旦用错,线上预测结果就不可信。










