数组中的 Numpy 零

Numpy zeros in array

我正在尝试从 numpy 中获得最大性能,并且想知道是否有更好的方法来计算带有大量零的数组的点积 例如:

a = np.array([[0, 3, 0], [1, 0, 1]])
print a.dot([1, 2, 5])

这是一个小例子,但如果我们有一个更大的数组,可以说数组中的任何位置都有 80% 的零,我的问题是是否有更好或更快的方法来计算点积什么时候有这么多零?

In [269]: from scipy import sparse
In [270]: M=sparse.random(1000,1000,.1, 'csr')
In [271]: MA = M.A
In [272]: timeit M*M.T
10 loops, best of 3: 64 ms per loop
In [273]: timeit MA@MA.T
10 loops, best of 3: 60.4 ms per loop

我定义了一个具有指定稀疏度的随机稀疏矩阵,10%:

In [274]: M
Out[274]: 
<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
    with 100000 stored elements in Compressed Sparse Row format>
In [275]: np.allclose(MA@MA.T, (M*M.T).A)
Out[275]: True

@dot 的运算符形式(参见 np.matmul)。所以在这个 10% 的稀疏度下,这两种方法的时间相同(没有任何转换 to/from 稀疏)。

对于这个随机矩阵,M*M.T 结果是密集的:

In [282]: (M*M.T)
Out[282]: 
<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
    with 999964 stored elements in Compressed Sparse Row format>

稀疏时间在很大程度上取决于稀疏性;密集的时间一点也不

In [295]: M=sparse.random(1000,1000,.01, 'csr'); MA=M.A
In [296]: timeit M*M.T
100 loops, best of 3: 2.44 ms per loop
In [297]: timeit MA@MA.T
10 loops, best of 3: 56.3 ms per loop
In [298]: M=sparse.random(1000,1000,.2, 'csr'); MA=M.A
In [299]: timeit M*M.T
10 loops, best of 3: 175 ms per loop
In [300]: timeit MA@MA.T
10 loops, best of 3: 56.3 ms per loop

往返稀疏和返回,时间从 60 毫秒跳到 100 毫秒

In [302]: %%timeit
     ...: M1=sparse.csr_matrix(MA)
     ...: (M1*M1.T).A
     ...: 
10 loops, best of 3: 104 ms per loop