使用Scipy在Python中使用大而密集的2d数组构建稀疏矩阵

时间:2015-08-29 08:27:48

标签: python scipy sparse-matrix

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

当给出更密集的2d数组(更少的零元素)时,问题就会出现,进程因错误而中断:

  

值错误:无法识别的csr_matrix构造函数用法

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

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

所以我的问题是:

- 构建csr_matrix取决于2d数组的稀疏程度如何?限制是什么?

- 我如何确保程序在处理这些错误的过程中不会被中断?

- 任何替代解决方案?

提前致谢

2 个答案:

答案 0 :(得分:1)

使用较小的数字,您的方法有效:

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)])

导致某种错误,很可能是“太大”或“记忆”。该错误被捕获,并以此“无法识别的...”消息重新发布。

尝试

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

我怀疑它会为您提供更详细的错误消息。

答案 1 :(得分:0)

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

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