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

如何为二维NumPy数组的每一行计算加权直方图数据?

解决方案:按行计算带权重的NumPy直方图

问题原因分析

你之前误用np.apply_along_axis的核心问题是:该函数会将指定轴上的元素展平为一维数组传递给包装函数,但你的wrapper却假设输入是二维的(4,2)数组,导致索引逻辑错误,最终输出形状异常。


方法1:修正np.apply_along_axis的用法

调整包装函数,将传入的一维数组重新reshape为预期的(n,2)结构,再执行直方图计算:

import numpy as np

data = np.array([[1,3,4,5],[2,1,5,4],[3,3,1,6],[1,2,2,2]])
weights = np.array([[1,1,2,0.4],[1,3,1,1],[1,1,6,5],[1,1,1,1]])
binn = np.array([0,1,3,4,7,10])

def wrapper(arr):
    # 将一维数组reshape为(4,2),恢复数据-权重对结构
    data_weights = arr.reshape(-1, 2)
    h, _ = np.histogram(data_weights[:,0], bins=binn, weights=data_weights[:,1])
    return h

arrs = np.concatenate((data[...,None], weights[...,None]), axis=-1)
h = np.apply_along_axis(wrapper, axis=1, arrs)

print(h)
# 输出:
# [[0.  1.  1.  2.4 0. ]
#  [0.  4.  0.  2.  0. ]
#  [0.  6.  2.  5.  0. ]
#  [0.  4.  0.  0.  0. ]]
print(h.shape)  # (4,5),符合预期

注意:np.apply_along_axis底层仍基于循环实现,性能不如纯向量化方法。


方法2:纯向量化实现(推荐)

利用np.digitize获取每个数据点的bin索引,再通过np.add.at按行累加权重,完全避免循环:

import numpy as np

data = np.array([[1,3,4,5],[2,1,5,4],[3,3,1,6],[1,2,2,2]])
weights = np.array([[1,1,2,0.4],[1,3,1,1],[1,1,6,5],[1,1,1,1]])
binn = np.array([0,1,3,4,7,10])

# 1. 获取每个数据点对应的bin索引(从0开始)
bin_indices = np.digitize(data, bins=binn) - 1

# 2. 初始化输出数组
output = np.zeros((data.shape[0], len(binn)-1), dtype=np.float64)

# 3. 构造行、列索引的扁平化数组,用于批量累加权重
rows = np.repeat(np.arange(data.shape[0]), data.shape[1])
cols = bin_indices.flatten()
weights_flat = weights.flatten()

# 4. 按(行,列)位置累加权重
np.add.at(output, (rows, cols), weights_flat)

print(output)
# 输出与预期一致:
# [[0.  1.  1.  2.4 0. ]
#  [0.  4.  0.  2.  0. ]
#  [0.  6.  2.  5.  0. ]
#  [0.  4.  0.  0.  0. ]]

这种方法完全基于NumPy的向量化操作,处理大规模数据时性能远优于apply_along_axis。


内容的提问来源于stack exchange,提问作者OliverBunting

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 06:57:08