矩阵归一化是数据预处理阶段的核心操作之一,Min-Max缩放法作为最常用的归一化方式,核心逻辑是对每个特征维度的数值做线性变换,让结果落在预设的区间范围内,最常见的目标区间是0到1。使用NumPy实现这个操作可以充分利用其向量化计算能力,大幅提升处理效率,不需要编写复杂的循环逻辑。

Min-Max缩放法原理说明
Min-Max缩放的公式可以表示为:
X_norm = (X - X_min) / (X_max - X_min)
其中X是原始矩阵,X_min是矩阵中对应维度的最小值,X_max是对应维度的最大值。如果目标区间不是0到1,比如要映射到a到b的区间,公式可以调整为:
X_norm = a + (X - X_min) * (b - a) / (X_max - X_min)
使用NumPy实现时,需要明确是按行还是按列计算最值,默认情况下我们按列处理,也就是每个特征维度单独做归一化,符合大多数机器学习的特征处理习惯。
基础实现代码
下面是一维数组和二维矩阵的基础归一化实现:
import numpy as np
# 一维数组归一化示例
arr = np.array([10, 20, 30, 40, 50])
arr_min = arr.min()
arr_max = arr.max()
# 避免除零,当最大值等于最小值时直接返回0数组
if arr_max == arr_min:
arr_norm = np.zeros_like(arr, dtype=float)
else:
arr_norm = (arr - arr_min) / (arr_max - arr_min)
print("一维数组归一化结果:", arr_norm)
# 二维矩阵按列归一化示例
matrix = np.array([[1, 100, 2000],
[2, 150, 1800],
[3, 200, 2200],
[4, 250, 1900]])
# axis=0表示按列计算最值,keepdims=True保持维度,方便后续广播计算
matrix_min = matrix.min(axis=0, keepdims=True)
matrix_max = matrix.max(axis=0, keepdims=True)
# 处理最大值等于最小值的情况
mask = matrix_max == matrix_min
matrix_norm = np.zeros_like(matrix, dtype=float)
# 对不需要处理除零的列做归一化
normal_cols = ~mask.flatten()
matrix_norm[:, normal_cols] = (matrix[:, normal_cols] - matrix_min[:, normal_cols]) / (matrix_max[:, normal_cols] - matrix_min[:, normal_cols])
print("二维矩阵按列归一化结果:")
print(matrix_norm)
封装为通用函数
为了方便重复使用,我们可以把逻辑封装成通用函数,支持指定归一化区间和目标轴:
import numpy as np
def min_max_normalize(matrix, axis=0, feature_range=(0, 1)):
"""
NumPy实现Min-Max矩阵归一化
:param matrix: 输入矩阵,支持任意维度
:param axis: 计算最值的轴,None表示全局计算,0表示按列,1表示按行
:param feature_range: 目标区间,默认(0,1)
:return: 归一化后的矩阵
"""
a, b = feature_range
matrix = np.asarray(matrix, dtype=float)
# 计算最值,保持维度方便广播
if axis is None:
min_val = matrix.min(keepdims=True)
max_val = matrix.max(keepdims=True)
else:
min_val = matrix.min(axis=axis, keepdims=True)
max_val = matrix.max(axis=axis, keepdims=True)
# 处理最大值等于最小值的情况
diff = max_val - min_val
diff[diff == 0] = 1 # 避免除零,此时分子也为0,结果为0,符合逻辑
# 计算归一化结果
norm_matrix = a + (matrix - min_val) * (b - a) / diff
return norm_matrix
# 测试通用函数
test_matrix = np.array([[5, 10, 15],
[10, 20, 30],
[15, 30, 45]])
# 按行归一化到0-1区间
row_norm = min_max_normalize(test_matrix, axis=1)
print("按行归一化结果:")
print(row_norm)
# 全局归一化到-1到1区间
global_norm = min_max_normalize(test_matrix, axis=None, feature_range=(-1, 1))
print("全局归一化到-1到1区间结果:")
print(global_norm)
常见问题说明
- 除零问题:当某一维度的所有数值都相同时,max-min为0,此时直接做除法会报错,上述实现中已经做了兼容处理,这种情况下该维度的归一化结果会全部为0,符合逻辑。
- 维度匹配:计算最值时一定要使用keepdims=True参数,否则得到的最值数组维度会和原矩阵不匹配,无法直接使用广播机制做运算。
- 数据类型:建议将输入矩阵转为float类型再做计算,避免整数除法导致的精度丢失问题。
应用场景说明
Min-Max归一化后的矩阵可以直接用于机器学习模型的输入,比如神经网络、支持向量机等对特征尺度敏感的训练任务,也可以用于数据可视化前的数值缩放,让不同量纲的特征可以在同一坐标系下展示。如果后续需要处理新的测试数据,要注意使用训练集的min和max值做归一化,避免数据泄露问题。