如何优化Scipy稀疏矩阵2D索引取数速度?现有方案存在性能瓶颈
高效实现方案
核心利用scipy.sparse.csr_matrix的原生广播索引能力,无Python层循环、无需提前将整个稀疏矩阵转稠密,性能远高于现有循环方案。
实现代码
import numpy as np import scipy.sparse # 测试数据生成逻辑和你提供的一致 x = np.random.randint(0, 1000, (1000, 100)) d = np.random.random((1000,1000)) d[d < 0.99] = 0 y = scipy.sparse.csr_matrix(d) # 优化后的核心逻辑 # 生成行索引数组,形状为(1000,1),和x的(1000,100)做广播匹配 row_idx = np.arange(y.shape[0])[:, np.newaxis] z = y[row_idx, x].toarray()
性能表现
本地同测试环境下耗时约为2~3ms,比你现有最优的110ms方案提升40倍以上。
原理解释
- 构造的
row_idx为形状(N,1)的行索引数组,和形状(N,M)的x广播后,自动为x中每个位置的列索引匹配对应的行号,完全匹配z[i,j] = y[i, x[i,j]]的需求 - 整个索引操作由scipy底层C代码实现,没有Python层循环开销
- 仅最后将索引得到的结果转为稠密数组,无需处理整个y的稠密转换,内存占用也更低
内容的提问来源于stack exchange,提问作者distracted-biologist
相关产品推荐
相关产品推荐

