使用 Python 中的大而密集的二维数组构建稀疏矩阵,使用 Scipy

Building a sparse matrix using a big, dense 2d array in Python, using Scipy

我正在使用 Python 和 Scipy 库创建一个稀疏矩阵,特别是 csr_matrix(压缩稀疏行矩阵)。矩阵相当大,大约有 70000*70000 个元素。我将矩阵构建为二维数组,然后构造 csr_matrix,将二维数组作为参数。构建一个非常稀疏的矩阵很容易,没有任何问题。

当给出更密集的二维数组(零元素少得多)时,问题就出现了,过程因错误而中断:

Value Error: unrecognized csr_matrix constructor usage

我尝试在交互式 Python 环境中构建一个大小相同的密集矩阵,但得到了完全相同的错误。

from scipy import sparse
a = [[10 for i in range(70000)] for j in range(70000)]
mat = sparse.csr_matrix(a)

所以我的问题是:

-构造 csr_matrix 是否取决于二维数组的稀疏程度?限制是多少?

-如何确保程序不会在处理过程中因此类错误而中断?

-任何替代解决方案?

提前致谢

查看关于创建稀疏矩阵的最后两个示例:
http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.csr_matrix.html

您也可以在文档中找到其他问题的答案

对于较小的数字,您的方法有效:

In [20]: a=[[10 for i in range(1000)] for j in range(1000)]
In [21]: M=sparse.csr_matrix(a)
In [22]: M
Out[22]: 
<1000x1000 sparse matrix of type '<class 'numpy.int32'>'
    with 1000000 stored elements in Compressed Sparse Row format>

密度不是问题。大小大概是。我无法重现您的错误,因为当我尝试更大尺寸时,我的机器变慢了,我不得不中断该过程。

如文档中所述,csr_matrix 接受多种输入。它根据元素的数量识别它们。我必须查看代码才能记住确切的逻辑。但是一种方法需要一个包含 3 个数组或列表的元组,另一种方法需要一个包含 2 个项目的元组,第二个是另一个元组。第三个是一个 numpy 数组。你的情况,一个列表列表不适合任何一个,但它可能会尝试将它变成一个数组。

a = np.array([[10 for i in range(M)] for j in range(N)])

您的错误消息很可能是某种内存错误的结果 - 您试图创建太大的矩阵。一个 70000 平方的密集矩阵很大(至少在某些机器上是这样),而表示相同矩阵的稀疏矩阵会更大。它必须将每个元素存储 3 次 - 一次用于值,两次用于坐标。

该大小的真正稀疏矩阵之所以有效,是因为稀​​疏表示要小得多,大致与非零元素数量的 3 倍成正比。


scipy/sparse/compressed.py

class _cs_matrix(...):
    """base matrix class for compressed row and column oriented matrices"""
    def __init__(self, arg1, ...):
        <is arg1 a sparse matrix>
        <is arg1 a tuple>
       else:
            # must be dense
            try:
                arg1 = np.asarray(arg1)
            except:
                raise ValueError("unrecognized %s_matrix constructor usage" % self.format)

我猜它会尝试:

np.asarray([[10 for i in range(70000)] for j in range(70000)])

这会导致某种错误,很可能是 'too large' 或 'memory'。该错误已被捕获,并通过此 'unrecognized ..' 消息重新发布。

尝试

A = np.array(a)
M = sparse.csr_matrix(A)

我怀疑它会给您提供更多信息的错误消息。