为什么python上的稀疏矩阵计算太慢了

时间:2016-10-19 04:21:41

标签: python performance numpy scipy sparse-matrix

我使用的格式是csr稀疏矩阵,建议它是add和dot opertor最快的稀疏结构。我将其性能与np.array的add和dot运算符进行了比较。然而,稀疏矩阵的计算比密集格式下的情况慢得多,这似乎很奇怪。为什么?有没有更有效的方法来实现稀疏计算?

import numpy as np
import scipy.sparse as sp
import random

#%% generate dense vector
vector_length = 10000
nonzero_term = 200

x = np.zeros((vector_length, ))
y = np.zeros((vector_length, ))

index = random.sample(range(vector_length), nonzero_term)
x[index] = np.random.rand(nonzero_term)
index = random.sample(range(vector_length), nonzero_term)
y[index] = np.random.rand(nonzero_term)

#%% transform to sparse vector
x_sp = sp.csr_matrix(x)
y_sp = sp.csr_matrix(y)

#%% test

# dense add
%timeit [x + y]
# sparse add
%timeit [x_sp + y_sp]     
# dense dot
%timeit [x.dot(y)]
# sparse dot
%timeit [x_sp.dot(y_sp.T)] 

,结果显示

100000 loops, best of 3: 6.06 µs per loop
10000 loops, best of 3: 97.8 µs per loop
100000 loops, best of 3: 3.45 µs per loop
1000 loops, best of 3: 225 µs per loop

1 个答案:

答案 0 :(得分:1)

这两组操作都使用编译代码。但数据存储方式完全不同。

x.shape是(10000,);同样yx+y只需要分配一个相同形状的数组,并在c中有效地逐步通过3个数据缓冲区。

x_sp有200个非零值,值在x_sp.data中,其列索引在x_sp.indices中。有第三个数组x_sp.indptr,但只有2个值。同样适用于y_sp。但要添加它们,它必须单步执行4个数组,并将值分配给两个数组。即使在c中编码,也会有更多的工作。在我的测试用例x_sp+y_sp中有397个非零值。

使用这些1d数组(1行矩阵),dot涉及相同类型的单步执行值,只将它们全部加到一个最终值。

如果矩阵的密度足够低,稀疏计算可以更快。我认为,矩阵乘法的确比加法更真实。

总之,对于稀疏矩阵,每元素计算更复杂。因此,即使元素很少,总体时间也会更长。