我有一个大的( n = 50000 )块对角csr_matrix
M ,表示一组图的邻接矩阵。我必须多次使用密集numpy.array
v 乘以 M 。因此我使用M.dot(v)
。
令人惊讶的是,我发现首先将 M 转换为numpy.array
然后使用numpy.dot
要快得多。
为什么会这样呢?
答案 0 :(得分:4)
我没有足够的内存来在内存中保存50000x50000
密集矩阵并将其乘以50000
向量。但是在这里找到一些维度较低的测试。
设定:
import numpy as np
from scipy.sparse import csr_matrix
def make_csr(n, N):
rows = np.random.choice(N, n)
cols = np.random.choice(N, n)
data = np.ones(n)
return csr_matrix((data, (rows, cols)), shape=(N,N), dtype=np.float32)
上面的代码在n
矩阵中生成具有NxN
非零元素的稀疏矩阵。
矩阵
N = 5000
# Sparse matrices
A = make_csr(10*10, N) # ~100 non-zero
B = make_csr(100*100, N) # ~10000 non-zero
C = make_csr(1000*1000, N) # ~1000000 non-zero
D = make_csr(5000*5000, N) # ~25000000 non-zero
E = csr_matrix(np.random.randn(N,N), dtype=np.float32) # non-sparse
# Numpy dense arrays
An = A.todense()
Bn = B.todense()
Cn = C.todense()
Dn = D.todense()
En = E.todense()
b = np.random.randn(N)
时序:
>>> %timeit A.dot(b) # 9.63 µs per loop
>>> %timeit An.dot(b) # 41.6 ms per loop
>>> %timeit B.dot(b) # 41.3 µs per loop
>>> %timeit Bn.dot(b) # 41.2 ms per loop
>>> %timeit C.dot(b) # 3.2 ms per loop
>>> %timeit Cn.dot(b) # 41.2 ms per loop
>>> %timeit D.dot(b) # 35.4 ms per loop
>>> %timeit Dn.dot(b) # 43.2 ms per loop
>>> %timeit E.dot(b) # 55.5 ms per loop
>>> %timeit En.dot(b) # 43.4 ms per loop
A
和B
),它的速度提高了1000x
倍。 C
),它仍然会获得10x
加速。 D
由于索引中的重复会有一些0
,但概率上说不是很多),它仍然更快,而不是很多,但更快。E
),操作速度较慢,但速度不会太慢。 结论:您获得的加速取决于矩阵的稀疏性,但使用N = 5000
稀疏矩阵总是更快(只要他们有一些零条目)。
由于内存问题,我无法为N = 50000
尝试。您可以尝试使用上面的代码,并使用N
查看您的内容。