如何有效地将两个稀疏SciPy矩阵相乘并生成一个稠密Numpy数组?

h5qlskok  于 2022-11-10  发布在  其他
关注(0)|答案(1)|浏览(146)

我想对两个稀疏的SciPy矩阵进行矩阵相乘。但是,结果不是稀疏的,所以我想将其存储为NumPy数组。
有没有可能高效地完成这一点,也就是说,不需要先创建一个“稀疏”矩阵,然后再转换它?我可以自由选择任何输入格式(无论哪个更高效)。
例如:两个10000x10000 99%的稀疏矩阵的乘积具有随机分布的零将是稠密的:

n = 10_000
a = np.random.randn(n, n) * (np.random.randint(100, size=(n, n)) == 0)
b = np.random.randn(n, n) * (np.random.randint(100, size=(n, n)) == 0)
c = a.dot(b)
np.count_nonzero(c) / c.size # should be 0.63
dgsult0t

dgsult0t1#

import numpy as np
from scipy import sparse

n = 10_000
a = sparse.csr_matrix(np.random.randn(n, n) * (np.random.randint(100, size=(n, n)) == 0))
b = sparse.csr_matrix(np.random.randn(n, n) * (np.random.randint(100, size=(n, n)) == 0))
c = a.dot(b)

>>> c
<10000x10000 sparse matrix of type '<class 'numpy.float64'>'
    with 63132806 stored elements in Compressed Sparse Row format>

是的,这是一种非常低效的存储矩阵的方法。但是在scipy中没有办法直接转换为dense。您可以使用sparseBLAS函数直接转换为dense(在您描述的用例中存在)。
我使用了一个python wrapper for MKL,它 Package 了mkl_sparse_spmmd

from sparse_dot_mkl import dot_product_mkl

c_dense = dot_product_mkl(a, b, dense=True)

>>>> np.sum(c_dense != 0)
63132806

它也是线程化的,所以它比scipy快得多。安装MKL是留给读者的(尽管conda install -c intel mkl可能是最简单的)

相关问题