如何在Python中向稀疏矩阵添加稀疏行?

Ébe*_*aac 3 python numpy scipy sparse-matrix

这个任务在 NumPy 中非常简单,就像这样

import numpy as np

a= np.array([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]])
a + a[1]
Run Code Online (Sandbox Code Playgroud)

输出:

array([[ 4,  4,  9,  2, 16],
       [ 6,  4, 12,  4, 14],
       [ 3,  2,  6, 10,  7],
       [ 4,  2,  6,  2, 10]])
Run Code Online (Sandbox Code Playgroud)

查看向量维度如何自动广播到矩阵的每一行。

但当涉及到稀疏矩阵时,就会出现维度不匹配的错误。

from scipy.sparse import *

a= csr_matrix([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]])
a + a[1]
Run Code Online (Sandbox Code Playgroud)

输出:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-32-74c48fe5106e> in <module>()
      2 
      3 a= csr_matrix([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]])
----> 4 a + a[1]

/opt/anaconda2/lib/python2.7/site-packages/scipy/sparse/compressed.pyc in __add__(self, other)
    337         elif isspmatrix(other):
    338             if (other.shape != self.shape):
--> 339                 raise ValueError("inconsistent shapes")
    340 
    341             return self._binopt(other,'_plus_')

ValueError: inconsistent shapes
Run Code Online (Sandbox Code Playgroud)

有一个用于稀疏乘法的函数,例如a.multiply(a[1])for a * a[1](它完美地完成了它的工作),但我找不到用于加法的函数。

我是稀疏矩阵的新手。请帮忙。

hpa*_*ulj 6

numpy稀疏矩阵尚未实现样式广播。

乘法,特别是矩阵乘法,已经很发达了。事实上,诸如行求和和行选择之类的操作是作为矩阵乘法实现的 - 例如M * <column vector of 1s>。乘法通常会产生一个同样稀疏(甚至更稀疏)的矩阵。

加法/减法还没有很发达。它通常会产生更密集的矩阵。极端情况是向所有元素添加标量。即使在你的例子中,结果也是密集的。和aa[1,:]必须非常稀疏才能证明纯稀疏加法的合理性。

In [713]: a= np.array([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]])
In [714]: aM = sparse.csr_matrix(a)
In [715]: aM
Out[715]: 
<4x5 sparse matrix of type '<class 'numpy.int32'>'
    with 12 stored elements in Compressed Sparse Row format>
Run Code Online (Sandbox Code Playgroud)

我们可以通过矩阵乘法复制所选行 - 首先是广播密集方法:

In [719]: np.ones((4,1))*aM[1,:]
Out[719]: 
array([[ 3.,  2.,  6.,  2.,  7.],
       [ 3.,  2.,  6.,  2.,  7.],
       [ 3.,  2.,  6.,  2.,  7.],
       [ 3.,  2.,  6.,  2.,  7.]])
In [720]: np.ones((4,1))*aM[1,:]+aM    # dense matrix addition
Out[720]: 
matrix([[  4.,   4.,   9.,   2.,  16.],
        [  6.,   4.,  12.,   4.,  14.],
        [  3.,   2.,   6.,  10.,   7.],
        [  4.,   2.,   6.,   2.,  10.]])
Run Code Online (Sandbox Code Playgroud)

稀疏矩阵乘法:

In [721]: sparse.csr_matrix(np.ones((4,1)))*aM[1,:]
Out[721]: 
<4x5 sparse matrix of type '<class 'numpy.float64'>'
    with 20 stored elements in Compressed Sparse Row format>
Run Code Online (Sandbox Code Playgroud)

稀疏矩阵加法:

In [722]: sparse.csr_matrix(np.ones((4,1)))*aM[1,:]+aM
Out[722]: 
<4x5 sparse matrix of type '<class 'numpy.float64'>'
    with 20 stored elements in Compressed Sparse Row format>
In [723]: _.A
Out[723]: 
array([[  4.,   4.,   9.,   2.,  16.],
       [  6.,   4.,  12.,   4.,  14.],
       [  3.,   2.,   6.,  10.,   7.],
       [  4.,   2.,   6.,   2.,  10.]])
Run Code Online (Sandbox Code Playgroud)

aM如果稀疏的话,尤其是稀疏的话,这将是一个更好的演示aM[1:]。我还可以指定np.onesas intdtype 来匹配aM。并且将其做成csc矩阵会更加紧凑。