You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何numpy.apply_along_axis指定不同axis却返回相同结果?

为什么np.apply_along_axis的axis参数对我的归一化函数无效?

先还原你的场景:
你有一个存储分数的NumPy数组:

import numpy as np

# 你的scores数组
scores = np.array([[-1.354 , 0. , 0.6921, ..., -0.1972, -0.0454, -0.1233],
       [-1.6837, 0. , 0.7019, ..., -0.1534, 0.0536, -0.0269],
       [-1.4549, -0.346 , 0.7698, ..., 0.385 , 0.3527, 0.0277],
       ...,
       [-0.7322, 1.7791, 1.5935, ..., 0.515 , 1.0949, 0.3007],
       [-0.3222, 1.2375, 1.6012, ..., 0.4675, 0.5924, 0.1081],
       [-1.4317, 0. , 0.7675, ..., -0.3711, -0.2111, -0.2084]])
print(scores.shape)  # (7, 1324)

你尝试用np.apply_along_axis结合lambda函数做[-1,1]范围的归一化,分别指定axis=0和axis=1,但得到的结果完全相同:

# axis=0时
normlized_scores = np.apply_along_axis(lambda x, mini=np.amin(scores), maxi=np.amax(scores): 2*((x-mini)/(maxi-mini))-1, 0, scores)

# axis=1时
normlized_scores = np.apply_along_axis(lambda x, mini=np.amin(scores), maxi=np.amax(scores): 2*((x-mini)/(maxi-mini))-1, 1, scores)

而np.sum用axis参数能得到符合预期的不同形状结果,这让你很困惑。

问题根源:你用了全局的min/max,而非当前轴方向子数组的min/max

你在lambda函数里定义的mini=np.amin(scores)和maxi=np.amax(scores)是整个scores数组的全局最小值和最大值,不管np.apply_along_axis遍历哪个轴方向的子数组(列或行),你的归一化计算都是基于全局的min/max来处理每个元素,自然得到的结果完全一致。

至于返回数组形状相同的问题:因为你的lambda函数只是对输入的子数组x的每个元素做相同的数值变换,没有改变子数组的长度,所以最终输出的数组形状始终和原数组一致,和指定的axis参数无关。

正确的做法:在lambda里计算当前子数组的min/max

要让归一化受axis参数影响,你需要针对每个被处理的子数组(列或行)计算它自己的min和max,修改后的代码如下:

按列归一化(axis=0)

normlized_scores_axis0 = np.apply_along_axis(
    lambda x: 2 * ((x - np.amin(x)) / (np.amax(x) - np.amin(x))) - 1,
    0,
    scores
)

这里针对每一列(每个长度为7的子数组x),计算该列的min和max来做归一化。

按行归一化(axis=1)

normlized_scores_axis1 = np.apply_along_axis(
    lambda x: 2 * ((x - np.amin(x)) / (np.amax(x) - np.amin(x))) - 1,
    1,
    scores
)

这里针对每一行(每个长度为1324的子数组x),计算该行的min和max来做归一化。

额外提示:用原生NumPy函数更高效

其实np.apply_along_axis在性能上不如原生的向量化操作,你可以用np.min和np.max指定axis参数来实现更高效的归一化:

按列归一化

min_col = np.min(scores, axis=0)
max_col = np.max(scores, axis=0)
norm_axis0 = 2 * ((scores - min_col) / (max_col - min_col)) - 1

按行归一化

min_row = np.min(scores, axis=1, keepdims=True)
max_row = np.max(scores, axis=1, keepdims=True)
norm_axis1 = 2 * ((scores - min_row) / (max_row - min_row)) - 1

这里keepdims=True是为了让min/max的形状和原数组兼容,方便广播运算。


内容的提问来源于stack exchange,提问作者Adam Bellaïche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 15:57:47