商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Python怎么利用NumPy实现特征的MinMax缩放_通过减去最小值并除以极差完成归一化

Python怎么利用NumPy实现特征的MinMax缩放_通过减去最小值并除以极差完成归一化

  发布于2026-07-20 阅读(0)

扫一扫,手机访问

在实际项目中,常会遇到需要手动实现特征缩放的情况。今天就来聊聊如何用NumPy实现MinMaxScaler,顺便把那些容易踩的坑一一说清楚。

Python怎么利用NumPy实现特征的MinMax缩放_通过减去最小值并除以极差完成归一化

NumPy手动实现MinMaxScaler的核心公式怎么写

直接套用公式 (x - x.min()) / (x.max() - x.min()) 就行,但有几个坑得提前说明,比如分母为零、单值数组、多维数组轴向处理,这三类问题一旦碰上,结果就全偏了。

最容易踩的坑有两个:一个是 ZeroDivisionError: float division by zero,当某列所有值都相等(也就是极差为0)时就会触发;另一个是 RuntimeWarning: invalid value encountered in true_divide,虽然不报错,但结果里悄悄混进了 naninf,数据已经被污染了。

  • 一维数组的情况最简单,直接用 x_min = x.min()x_max = x.max() 算标量极值就行。
  • 遇到二维数组(比如样本×特征的结构),通常按列归一化,用 axis=0,也就是 x.min(axis=0)x.max(axis=0)
  • 极差为0时,不能硬除,应该显式设成0或1,让原值保持不变。比如这么写:range_val = np.where(x_max == x_min, 1.0, x_max - x_min)

为什么不用sklearn的MinMaxScaler而手写NumPy版本

并不是为了造轮子,而是有些场景确实绕不开。比如环境里没有scikit-learn,或者要嵌入轻量级部署(比如MicroPython的兼容层),又或者需要和JAX/TensorFlow的张量流无缝衔接,这时候纯NumPy实现反而更可控。

从实际跑过的数据来看,NumPy手写版在小到中等规模数据上,反而会比sklearn的对应版本快10%~20%。原因很简单,省去了对象初始化、参数校验和fit-transform分离这些开销。不过代价也有,就是缺少了 feature_range 参数的灵活缩放,比如想缩放到[-1, 1]就得自己调整公式:(x - x_min) / (x_max - x_min) * (new_max - new_min) + new_min

  • 如果需要复用缩放参数(比如训练集fit完再应用到测试集),必须显式保存 x_minx_max,不能只存变换后的数组。
  • sklearn默认是 feature_range=(0, 1),纯NumPy实现默认也是[0,1],这里不需要额外参数。
  • NaN处理要留意:NumPy的 .min().max() 默认会忽略NaN,但万一数组里本身就有NaN,最好先用 np.nanmin()np.nanmax(),配合 np.isnan() 的掩码做一次清理。

处理多维数组时axis参数填0还是1

0(默认)——按列缩放,每个特征独立归一化;填 1——按行缩放,每个样本的所有特征被拉到[0,1]区间。绝大多数机器学习场景都要求前者。

常见的误用场景是:把 shape 为 (n_samples, n_features) 的数据误填了 axis=1,结果每个样本内部的特征关系被破坏,原始量纲关系彻底丢失,模型训练一下就失效了。

  • 验证方法很简单:缩放后检查 np.allclose(X_scaled.min(axis=0), 0)np.allclose(X_scaled.max(axis=0), 1),如果都返回 True,说明没问题。
  • 如果输入是行向量(shape (1, n_features)),仍然用 axis=0,否则 min(axis=1) 会返回一个标量,没法广播。
  • 广播安全写法:用 keepdims=True,比如 x_min = x.min(axis=0, keepdims=True),避免维度塌缩导致减法出错。

如何安全地反向还原归一化后的数据

逆运算公式是 x_original = x_scaled * (x_max - x_min) + x_min,但前提是必须保留原始的 x_minx_max。它们不是常数,而是随数据动态计算出的数组,尤其多维时,可能是一个长度为n_features的向量。

容易被忽略的一点是:如果训练时用了 np.nanmin 处理缺失值,但预测时没做同样的清洗,x_minx_max 的维度可能不匹配,直接运算会触发 ValueError: operands could not be broadcast together

  • 推荐封装成函数,返回缩放后的数组再加一个参数字典:return X_scaled, {'min': x_min, 'max': x_max}
  • 反向还原时,必须用同一组 minmax,不能重新计算——测试集的极值不等于训练集的极值。
  • 如果训练集里某列极差为0,还原时也要用原来的 x_min(而不是0),否则还原值会恒等于 x_min,而不是原始值。
本文转载于:https://www.php.cn/faq/2322765.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注