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

Numpy矩阵高效聚合与值复制的实现方法

高效实现矩阵的聚合与扩展操作(Numpy向量化方案)

一、矩阵聚合(N×N → P×P)

针对多对一的维度映射关系,推荐两种Numpy原生的高效向量化实现,彻底替代低效的嵌套循环:

准备工作:将字典映射转为索引数组

先把原维度到新维度的字典映射转换为Numpy数组,这是后续所有操作的基础:

import numpy as np

# 示例矩阵
m = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]])
# 原维度到新维度的映射字典
big2small = {0:0, 1:1, 2:0, 3:1}
# 转换为索引数组:索引对应原维度下标,值对应新维度下标
idx = np.array([big2small[i] for i in range(m.shape[0])])
# idx = array([0, 1, 0, 1])

方法1:使用np.add.at直接累加(最直观的向量化累加)

利用np.add.at实现对目标矩阵的批量累加操作,完全规避循环:

# 新矩阵的尺寸P
p = idx.max() + 1
# 初始化结果矩阵
result = np.zeros((p, p), dtype=m.dtype)
# 按映射关系批量累加原矩阵的值到结果矩阵
np.add.at(result, (idx[:, None], idx), m)

print(result)
# 输出:
# [[24 28]
#  [40 44]]

该方法直接操作底层数组,效率极高,适配1000×1000级别的大矩阵。

方法2:利用矩阵乘法(基于One-Hot编码)

通过将索引转换为One-Hot矩阵,利用矩阵乘法实现分组求和,数学逻辑清晰:

p = idx.max() + 1
# 生成One-Hot矩阵,shape=(N, P)
one_hot = np.eye(p)[idx]
# 矩阵乘法实现行、列的分组求和
result = one_hot.T @ m @ one_hot

print(result)
# 输出与方法1一致

矩阵乘法依托Numpy的BLAS优化,性能与np.add.at相当,适合偏好数学表达的场景。


二、矩阵扩展(P×P → N×N)

反向操作时,直接利用索引数组的广播特性即可实现值的批量复制,完全向量化:

# 示例小矩阵
small_m = np.array([[1,2],[3,4]])
# 利用索引数组的广播索引,直接生成扩展矩阵
expanded_m = small_m[idx[:, None], idx]

print(expanded_m)
# 输出:
# [[1 2 1 2]
#  [3 4 3 4]
#  [1 2 1 2]
#  [3 4 3 4]]

该操作完全依赖Numpy的索引优化,无任何循环,是效率最高的实现方式。


注意事项

如果原映射字典的新维度下标不是连续整数(比如新索引为[2,3,2,3]),可先通过np.unique转换为连续下标,处理完成后再映射回原索引:

# 示例非连续映射
big2small = {0:2, 1:3, 2:2, 3:3}
values = list(big2small.values())
# 转换为连续下标
unique_new_idx, idx = np.unique(values, return_inverse=True)
# 此时idx = array([0,1,0,1]),后续操作同上述方案
# 处理完成后,可通过unique_new_idx将结果的下标映射回原索引

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:45:35