首页 文章

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

提问于
浏览
5

我想从稀疏矩阵中删除对角元素 . 由于矩阵是稀疏的,因此一旦移除就不应存储这些元素 .

Scipy提供了一种设置对角元素值的方法:setdiag

如果我使用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>

但是使用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.]])

通过密集阵列,我们当然有:

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

这是有意的吗?如果是这样,是否由于csr矩阵的压缩格式?除了从稀疏到密集再到稀疏之外,还有其他解决方法吗?

1 回答

  • 5

    简单地将元素设置为0不会改变 csr 矩阵的稀疏性 . 你必须申请 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>
    

    由于更改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
    

相关问题