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

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

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

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

dgsult0t1#

  1. import numpy as np
  2. from scipy import sparse
  3. n = 10_000
  4. a = sparse.csr_matrix(np.random.randn(n, n) * (np.random.randint(100, size=(n, n)) == 0))
  5. b = sparse.csr_matrix(np.random.randn(n, n) * (np.random.randint(100, size=(n, n)) == 0))
  6. c = a.dot(b)
  7. >>> c
  8. <10000x10000 sparse matrix of type '<class 'numpy.float64'>'
  9. with 63132806 stored elements in Compressed Sparse Row format>

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

  1. from sparse_dot_mkl import dot_product_mkl
  2. c_dense = dot_product_mkl(a, b, dense=True)
  3. >>>> np.sum(c_dense != 0)
  4. 63132806

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

展开查看全部

相关问题