Numpy scipy超稀疏矩阵乘法速度非常慢

Numpy scipy超稀疏矩阵乘法速度非常慢,numpy,sparse-matrix,Numpy,Sparse Matrix,有一些帖子讨论了稀疏矩阵乘法的性能,但它们似乎并没有回答我的问题 这是基准代码 首先,构造一个空间矩阵 在[1]中:从scipy.sparse导入dok_矩阵 在[2]:M=dok_matrix100,1中,非常大的第二维度带来了问题,即使稀疏度非常小 In [12]: Mr = M.tocsr() In [20]: Mr Out[20]: <100x4294967295 sparse matrix of type '<class 'numpy.float32'>'

有一些帖子讨论了稀疏矩阵乘法的性能,但它们似乎并没有回答我的问题

这是基准代码

首先,构造一个空间矩阵 在[1]中:从scipy.sparse导入dok_矩阵
在[2]:M=dok_matrix100,1中,非常大的第二维度带来了问题,即使稀疏度非常小

In [12]: Mr = M.tocsr()
In [20]: Mr
Out[20]: 
<100x4294967295 sparse matrix of type '<class 'numpy.float32'>'
    with 10000 stored elements in Compressed Sparse Row format>
但当我这么做的时候Mr@Mr.T,当它试图将T先生转换为“csr”时,我得到一个错误。也就是说,乘法需要相同的格式:

In [22]: Mr.T.tocsr()
Traceback (most recent call last):
  File "<ipython-input-22-a376906f557e>", line 1, in <module>
    Mr.T.tocsr()
  File "/usr/local/lib/python3.8/dist-packages/scipy/sparse/csc.py", line 138, in tocsr
    indptr = np.empty(M + 1, dtype=idx_dtype)
MemoryError: Unable to allocate 32.0 GiB for an array with shape (4294967296,) and data type int64
它试图用一个长4294967296的indptr制作一个矩阵。在我的内存有限的机器上产生错误。在您的计算机上,它一定是遇到了某种内存管理/交换任务,从而使其速度减慢


因此,即使nnz很小,极限维也会使速度变慢。

非常大的第二维会带来问题,即使稀疏度很小

In [12]: Mr = M.tocsr()
In [20]: Mr
Out[20]: 
<100x4294967295 sparse matrix of type '<class 'numpy.float32'>'
    with 10000 stored elements in Compressed Sparse Row format>
但当我这么做的时候Mr@Mr.T,当它试图将T先生转换为“csr”时,我得到一个错误。也就是说,乘法需要相同的格式:

In [22]: Mr.T.tocsr()
Traceback (most recent call last):
  File "<ipython-input-22-a376906f557e>", line 1, in <module>
    Mr.T.tocsr()
  File "/usr/local/lib/python3.8/dist-packages/scipy/sparse/csc.py", line 138, in tocsr
    indptr = np.empty(M + 1, dtype=idx_dtype)
MemoryError: Unable to allocate 32.0 GiB for an array with shape (4294967296,) and data type int64
它试图用一个长4294967296的indptr制作一个矩阵。在我的内存有限的机器上产生错误。在您的计算机上,它一定是遇到了某种内存管理/交换任务,从而使其速度减慢


因此,即使nnz很小,也正是极端维度使得速度变慢。

非常感谢您花时间对此进行详细分析!!是的,第二个dim非常大,事实上我不明白为什么在这么多非零元素的情况下会花费这么多内存。另外,如果我可以再添加一个观察值,scipy.sparse.random将首先创建一个巨大的索引列表,然后从中采样以创建一个伪稀疏矩阵,这是非常贪婪的内存,而且不能用于我的第二个dim,即OSYes杀死的ipython炮弹,这是一个最近的随机发生器-。选择随机标记的方法使用对所有可能值的简单选择。这是一种简单的方法,适用于一般的测试矩阵。非常感谢您花时间对此进行详细分析!!是的,第二个dim非常大,事实上我不明白为什么在这么多非零元素的情况下会花费这么多内存。另外,如果我可以再添加一个观察值,scipy.sparse.random将首先创建一个巨大的索引列表,然后从中采样以创建一个伪稀疏矩阵,这是非常贪婪的内存,而且不能用于我的第二个dim,即OSYes杀死的ipython炮弹,这是一个最近的随机发生器-。选择随机标记的方法使用对所有可能值的简单选择。这是一种简单的方法,适用于一般的测试矩阵。