2017-07-01 50 views
0

稀疏矩阵我有我用几个对角线构建稀疏矩阵:充满行和对角线

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

然而,这稀疏矩阵也有那些在最后一排的一个载体。有没有什么方法可以将它存储在稀疏矩阵中,还是我的构造效率低下,我应该使用密集矩阵?

+0

是什么让你觉得你不能存储它? –

+0

@PeterWood @PeterWood我可以想象,稀疏矩阵对于包含行,列或对角线信息进行了优化,一旦开始彼此交叉,从稀疏存储获得的内存变得可以忽略不计 - 因此不会被“scipy”支持。 – FooBar

+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)阵列。它“摆脱”了你粗糙的投入。 A.offsets是一个3元素数组。

A.tocoo()将值存储在3(295,)数组中(删除定义中的0)。 A 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> 

出于好奇,我试图vstackdia输出 - 它不喜欢它,因为平方数dia数据会过大。

lil格式
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 

分配不产生任何警告:

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大多数计算。