具有填充行和对角线的稀疏矩阵

时间:2017-07-01 21:07:40

标签: python matrix scipy sparse-matrix

我有一个使用几个对角线构建的稀疏矩阵:

A = diags([np.arange(100), np.arange(99), np.arange(99)], offsets=[0, -1, 1])

但是,这个稀疏矩阵在最后一行中也有一个向量。有没有办法将它存储在稀疏矩阵中,或者我的构造效率低下,我应该使用密集矩阵?

1 个答案:

答案 0 :(得分:2)

sparse.diags会生成一个特殊diagonal格式的稀疏矩阵:

In [591]: A = sparse.diags([np.arange(100), np.arange(99), np.arange(99)], offse
     ...: ts=[0, -1, 1])
In [592]: A
Out[592]: 
<100x100 sparse matrix of type '<class 'numpy.float64'>'
    with 298 stored elements (3 diagonals) in DIAgonal format>
In [593]: A.A
Out[593]: 
array([[  0.,   0.,   0., ...,   0.,   0.,   0.],
       [  0.,   1.,   1., ...,   0.,   0.,   0.],
       [  0.,   1.,   2., ...,   0.,   0.,   0.],
       ..., 
       [  0.,   0.,   0., ...,  97.,  97.,   0.],
       [  0.,   0.,   0., ...,  97.,  98.,  98.],
       [  0.,   0.,   0., ...,   0.,  98.,  99.]])

但是存储并不比其他稀疏格式更有效。其他格式必须存储相同的298值。他们只是对它们进行不同的索引。

我们可以用各种方式设置最后一行。

我们无法使用稀疏格式直接索引最后一行。

In [594]: A[-1,:]
...
TypeError: 'dia_matrix' object is not subscriptable

但我们可以将其转换为csr格式,并设置其行值:

In [595]: A.tocsr()[-1,:]
Out[595]: 
<1x100 sparse matrix of type '<class 'numpy.float64'>'
    with 2 stored elements in Compressed Sparse Row format>
In [596]: Ac = A.tocsr()
In [597]: Ac[-1,:]=1
/usr/local/lib/python3.5/dist-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive.
In [598]: Ac
Out[598]: 
<100x100 sparse matrix of type '<class 'numpy.float64'>'
    with 393 stored elements in Compressed Sparse Row format>
In [599]: Ac.A
Out[599]: 
array([[  0.,   0.,   0., ...,   0.,   0.,   0.],
       [  0.,   1.,   1., ...,   0.,   0.,   0.],
       [  0.,   1.,   2., ...,   0.,   0.,   0.],
       ..., 
       [  0.,   0.,   0., ...,  97.,  97.,   0.],
       [  0.,   0.,   0., ...,  97.,  98.,  98.],
       [  1.,   1.,   1., ...,   1.,   1.,   1.]])

在这里,我不担心稀疏性警告;对于动作迭代完成的情况,这意味着更多。我本可以使用tolil()代替。请记住,csr格式可用于计算。并且在组合矩阵块时使用coo格式。

我刚检查了sparse.dia_matrix代码。对于您的数组A.data是一个(3,100)数组。它正方形&#39;你衣衫褴褛的输入。 A.offsets是一个3元素数组。

A.tocoo()将值存储在3(295)个数组中(删除定义中的3 0&#39;)。 A.tocsr()存储2(295)个数组和一个(101,)indptr数组。因此dia格式更紧凑,但只要您可以使用格式。

要替换那些行,请使用sparse.vstackvstack使用coo格式构建新矩阵):

In [619]: B = sparse.vstack((A,np.ones((1,100))))
In [620]: B
Out[620]: 
<101x100 sparse matrix of type '<class 'numpy.float64'>'
    with 395 stored elements in COOrdinate format>

出于好奇,我尝试了vstack dia输出 - 它不喜欢它,因为平方dia数据太大了。

In [621]: B = sparse.vstack((A,np.ones((1,100))),format='dia')
/usr/local/lib/python3.5/dist-packages/scipy/sparse/coo.py:359: SparseEfficiencyWarning: Constructing a DIA matrix with 102 diagonals is inefficient

使用lil格式的分配不会产生任何警告:

In [624]: Al = A.tolil()
In [625]: Al[-1,:]=1
In [626]: Al
Out[626]: 
<100x100 sparse matrix of type '<class 'numpy.float64'>'
    with 393 stored elements in LInked List format>

对于大多数计算,它也会转换为csr