我有一种情况需要从稀疏矩阵中提取单行并将其点积与密集行相对应。使用scipy的csr_matrix,这似乎比使用numpy的密集数组乘法慢得多。这对我来说是令人惊讶的,因为我预计稀疏点产品将涉及明显更少的操作。这是一个例子:
import timeit as ti
sparse_setup = 'import numpy as np; import scipy.sparse as si;' + \
'u = si.eye(10000).tocsr()[10];' + \
'v = np.random.randint(100, size=10000)'
dense_setup = 'import numpy as np; u = np.eye(10000)[10];' + \
'v = np.random.randint(100, size=10000)'
ti.timeit('u.dot(v)', setup=sparse_setup, number=100000)
2.788649031019304
ti.timeit('u.dot(v)', setup=dense_setup, number=100000)
2.179030169005273
对于矩阵向量乘法,稀疏表示获胜,但在这种情况下不是。我尝试使用csc_matrix,但性能更差:
>>> sparse_setup = 'import numpy as np; import scipy.sparse as si;' + \
... 'u = si.eye(10000).tocsc()[10];' + \
... 'v = np.random.randint(100, size=10000)'
>>> ti.timeit('u.dot(v)', setup=sparse_setup, number=100000)
7.0045155879925005
为什么numpy会在这种情况下击败scipy.sparse?是否有一种矩阵格式,这种计算速度更快?
答案 0 :(得分:1)
CSR / CSC向量产品调用每次调用都有几微秒的开销,执行一小部分Python代码,并处理编译代码中的参数(scipy.sparse._sparsetools.csr_matvec)。
在现代处理器上,计算矢量点产品非常快,因此在这种情况下,开销主导了计算时间。矩阵矢量产品本身更昂贵,而且类似的开销不可见。
为什么Numpy的开销较小?这主要是因为更好的代码优化; csr_matrix的性能可能会在这里得到改善。