Python无需计算AB矩阵乘积即可高效提取AB对角块的方法
高效实现思路
你不需要计算完整的AB矩阵,也不需要用Python层for循环逐列计算,核心可以基于矩阵乘法的局部性原理做优化:
- 矩阵乘积AB的第j列第i行的元素值,仅等于A的第i行和B的第j列的点积,和A、B其他位置的元素无关
- 你需要的是j从0到99区间内,AB第j列中
[10j : 10j+10]这10行的元素,只需要用到A中对应行区间的子块,以及B中对应列的向量,完全不需要计算其余99%的冗余元素
具体实现(NumPy版本)
用NumPy的向量化操作+einsum可以一次性完成批量计算,全程走C层实现,无Python循环开销:
import numpy as np # 输入矩阵A: (1000, 50), B: (50, 100) # 1. 生成A的分块行索引,共100组,每组10个连续行号 row_chunks = np.arange(1000).reshape(100, 10) # 2. 批量取出所有需要的A子块,形状为(100, 10, 50),对应100个10×50的子矩阵 A_sub = A[row_chunks] # 3. 批量完成矩阵乘:每个10×50的A子块乘B中对应的50×1列向量,最终输出形状为(10, 100) # 每一列正好对应你需要的10个元素,即AB[j列10j:10j+10行]的结果 result = np.einsum("ijk,ki->ji", A_sub, B)
性能说明
- 总计算量仅为全量计算AB矩阵的1%:全量AB需要做100050100=5e6次乘加运算,该方案仅需要1001050=5e4次乘加
- 无Python层循环开销,实际运行速度比逐列遍历的for循环快100倍以上,内存占用也远低于存储全量AB的方案
- 如果使用PyTorch等张量计算框架,逻辑完全一致,替换对应API即可在GPU上进一步加速
注:你问题描述中写的切片序列
A[0:10,0],A[10:20,1]...属于笔误,A仅50列,不存在j>49的列索引,上述实现是按照提取AB对应对角块的需求编写的。
内容的提问来源于stack exchange,提问作者Heydude
相关产品推荐
相关产品推荐

