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

时间:2017-07-12 04:25:51

标签: python numpy scipy sparse-matrix

这项任务在NumPy中非常简单,如此

array([[ 4,  4,  9,  2, 16],
       [ 6,  4, 12,  4, 14],
       [ 3,  2,  6, 10,  7],
       [ 4,  2,  6,  2, 10]])

输出:

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]

查看矢量尺寸如何自动广播到矩阵的每一行。

但是当涉及稀疏矩阵时,存在尺寸不匹配错误。

---------------------------------------------------------------------------
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

输出:

a.multiply(a[1])

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

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

2 个答案:

答案 0 :(得分:3)

稀疏矩阵尚未实现

#include <stdio.h> #include <Windows.h> static void EscapeDquote(char * const sz) { char *p = sz; BOOL bs = FALSE; for (; *p; ++p) { if (*p == '\\') { bs = !bs; continue; } if (*p == '\"') { if (bs) { /* discard prev char (backslash before dquote) overwrite with next char until null-termi */ char *q = --p; /* OLD version, not OK for GCC */ /* while(*q++ = *(q+1)); */ /* Safer version, works in GCC as well: */ while(*q = *(q+1)){++q;} } } bs = FALSE; } } int main() { /* "call \"D:\foo bar.exe\" */ char szTest[] = "call \\\"D:\\foo bar.exe\\\""; printf("Before = %s\n", szTest); EscapeDquote(szTest); printf("After = %s\n", szTest); return 0; } 样式广播。

乘法,特别是矩阵乘法,已得到很好的发展。实际上,诸如行和和行的选择之类的动作被实现为矩阵乘法 - 例如, numpy。乘法通常会产生一个稀疏的矩阵,如果不是这样的话。

加法/减法没有很好地发展。它通常会导致更密集的矩阵。极端情况是为所有元素添加标量。即使在您的示例中,结果也很密集。 M * <column vector of 1s>a都必须非常稀疏才能证明纯粹的稀疏加法。

a[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>

稀疏矩阵乘法:

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.]])

稀疏矩阵加法:

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>

如果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.]]) ,尤其是aM稀疏,这将是一个更好的示范。我也可以将aM[1:]指定为np.ones dtype以匹配int。使其成为aM矩阵会更紧凑。

答案 1 :(得分:0)

尝试:

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.todense()+a[1].todense()

它将是:

matrix([[ 4,  4,  9,  2, 16],
        [ 6,  4, 12,  4, 14],
        [ 3,  2,  6, 10,  7],
        [ 4,  2,  6,  2, 10]])

<强>更新

使添加矩阵b具有相同的维度并使用a[1]填充,然后添加它们:

from scipy.sparse import *
import numpy as np
an_array=np.array([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]])
a = csr_matrix(an_array)
b = csr_matrix([an_array[1] for i in range(len(an_array))])
a+b