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

如何避免循环实现Numpy数组按索引映射的批量求和操作?

高效解决Numpy数组按映射分组求和问题

核心思路

用Numpy的np.bincount实现向量化分组求和,彻底替代Python循环,适配十万级甚至更大规模的数组运算。bincount能根据给定索引数组,对权重数组元素做分组累加,完美匹配需求场景。

实现步骤

  1. 展开映射关系:把字典m的键值对转换成两个一维数组:
    • arr2_indices:展开所有arr2的索引(将字典值列表逐个展开)
    • arr1_indices:每个arr2索引对应的arr1索引(按对应次数重复字典的键)
  2. 调用np.bincount计算:以arr1_indices为分组依据,arr2[arr2_indices]为待求和权重,直接得到arr1的结果。

代码示例

import numpy as np

# 示例数据
m = {
    0: [0,1],
    1: [1,2],
    2: [3,4],
}
arr2 = np.array([1,5,7,9,12])
M = len(m)  # arr1的长度

# 展开映射关系
arr1_indices = []
arr2_indices = []
for idx1, idxs2 in m.items():
    arr1_indices.extend([idx1]*len(idxs2))
    arr2_indices.extend(idxs2)

# 转为Numpy数组
arr1_indices = np.array(arr1_indices)
arr2_indices = np.array(arr2_indices)

# 计算分组求和
arr1 = np.bincount(arr1_indices, weights=arr2[arr2_indices], minlength=M)

print(arr1)  # 输出: [ 6 12 21]

性能优势

np.bincount是C实现的向量化操作,比Python循环快数个数量级。十万级规模下,仅需一次轻量的映射展开(开销远低于循环),后续计算全由Numpy处理,彻底规避Python解释器的循环开销。

扩展适配其他聚合操作

如果需要执行求和之外的聚合逻辑,可结合Numpy其他函数实现:

  • 求均值:先通过bincount求和,再除以每个分组的元素个数(分组个数用np.bincount(arr1_indices)获取)
  • 求最大值:用np.maximum.at做原地向量化更新:
    arr1_max = np.zeros(M)
    np.maximum.at(arr1_max, arr1_indices, arr2[arr2_indices])
    print(arr1_max)  # 输出: [ 5.  7. 12.]
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:51:32