填充行和对角线的稀疏矩阵
Posted
技术标签:
【中文标题】填充行和对角线的稀疏矩阵【英文标题】:Sparse matrix with filled row and diagonal 【发布时间】:2017-07-01 21:07:40 【问题描述】:我有一个使用多个对角线构造的稀疏矩阵:
A = diags([np.arange(100), np.arange(99), np.arange(99)], offsets=[0, -1, 1])
然而,这个稀疏矩阵在最后一行也有一个向量。有没有办法将它存储在稀疏矩阵中,或者我的构造效率低下,我应该使用密集矩阵?
【问题讨论】:
是什么让你认为你不能存储它? @PeterWood 我可以想象稀疏矩阵已针对包含行、列或对角线信息进行了优化,一旦开始将它们相互交叉,从稀疏存储中获得的内存就可以忽略不计 - 因此不会得到scipy
的支持
最后一行真的需要在稀疏数组中吗?您可以将要乘以的向量的总和插入到最后一个条目中。
【参考方案1】:
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) 数组。它“消除”了您参差不齐的输入。 A.offsets
是一个 3 元素数组。
A.tocoo()
将值存储在 3 (295,) 个数组中(删除定义中的 3 个 0)。一个 A.tocsr()
存储 2 个 (295,) 数组加上一个 (101,) indptr
数组。所以dia
格式更紧凑,但前提是您可以使用该格式。
若要追加这些行,请使用sparse.vstack
(vstack
使用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>
出于好奇,我尝试使用dia
输出vstack
- 它不喜欢它,因为平方的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
。
【讨论】:
以上是关于填充行和对角线的稀疏矩阵的主要内容,如果未能解决你的问题,请参考以下文章