我有一个问题,需要从稀疏矩阵中提取一行并将其与密集矩阵的一行进行点积。使用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?是否有一种矩阵格式对此类计算更快?
sparse._sparsetools.csr_matvec
,这是一个已编译的函数。我需要查看scipy github以进一步了解。 - hpaulju
中非零值的数量(以及密集等效项)时,时间并没有发生变化。(u.data * v[u.indices]).sum()
更接近于您想象中的情况。它略微更快,但其时间仍不是O(k)。 - hpaulj