简体   繁体   English

从scipy的稀疏矩阵中删除对角线元素

[英]Removing diagonal elements from a sparse matrix in scipy

I want to remove diagonal elements from a sparse matrix. 我想从稀疏矩阵中删除对角线元素。 Since the matrix is sparse, these elements shouldn't be stored once removed. 由于矩阵是稀疏的,因此删除后就不应存储这些元素。

Scipy provides a method to set diagonal elements values: setdiag Scipy提供了一种设置对角元素值的方法: setdiag

If I try it using lil_matrix, it works: 如果我使用lil_matrix尝试它,它将起作用:

>>> a = np.ones((2,2))
>>> c = lil_matrix(a)
>>> c.setdiag(0)
>>> c
<2x2 sparse matrix of type '<type 'numpy.float64'>'
    with 2 stored elements in LInked List format>

However with csr_matrix, it seems diagonal elements are not removed from storage: 但是,对于csr_matrix,似乎对角线元素并未从存储中删除:

>>> b = csr_matrix(a)
>>> b
<2x2 sparse matrix of type '<type 'numpy.float64'>'
    with 4 stored elements in Compressed Sparse Row format>

>>> b.setdiag(0)
>>> b
<2x2 sparse matrix of type '<type 'numpy.float64'>'
    with 4 stored elements in Compressed Sparse Row format>

>>> b.toarray()
array([[ 0.,  1.],
       [ 1.,  0.]])

Through a dense array, we have of course: 通过密集阵列,我们当然可以:

>>> csr_matrix(b.toarray())
<2x2 sparse matrix of type '<type 'numpy.float64'>'
    with 2 stored elements in Compressed Sparse Row format>

Is that intended? 那是故意的吗? If so, is it due to the compressed format of csr matrices? 如果是这样,是否是由于csr矩阵的压缩格式? Is there any workaround else than going from sparse to dense to sparse again? 除了从稀疏到密集再到稀疏,还有其他解决方法吗?

Simply setting elements to 0 does not change the sparsity of a csr matrix. 简单地将元素设置为0不会改变csr矩阵的稀疏性。 You have to apply eliminate_zeros . 您必须应用eliminate_zeros

In [807]: a=sparse.csr_matrix(np.ones((2,2)))
In [808]: a
Out[808]: 
<2x2 sparse matrix of type '<class 'numpy.float64'>'
    with 4 stored elements in Compressed Sparse Row format>
In [809]: a.setdiag(0)
In [810]: a
Out[810]: 
<2x2 sparse matrix of type '<class 'numpy.float64'>'
    with 4 stored elements in Compressed Sparse Row format>
In [811]: a.eliminate_zeros()
In [812]: a
Out[812]: 
<2x2 sparse matrix of type '<class 'numpy.float64'>'
    with 2 stored elements in Compressed Sparse Row format>

Since changing the sparsity of a csr matrix is relatively expensive, they let you change values to 0 without changing sparsity. 由于更改csr矩阵的稀疏度是相对昂贵的,因此它们使您可以将值更改为0而不更改稀疏度。

In [829]: %%timeit a=sparse.csr_matrix(np.ones((1000,1000)))
     ...: a.setdiag(0)
100 loops, best of 3: 3.86 ms per loop

In [830]: %%timeit a=sparse.csr_matrix(np.ones((1000,1000)))
     ...: a.setdiag(0)
     ...: a.eliminate_zeros()
SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
10 loops, best of 3: 133 ms per loop

In [831]: %%timeit a=sparse.lil_matrix(np.ones((1000,1000)))
     ...: a.setdiag(0)
100 loops, best of 3: 14.1 ms per loop

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM