简体   繁体   English

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

[英]How to add a sparse row to a sparse matrix in Python?

This task is pretty trivial in NumPy like so 这样的任务在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]

Output: 输出:

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

See how the vector dimensions are automatically broadcasted to each row of the matrix. 了解矢量尺寸如何自动广播到矩阵的每一行。

But when it comes to sparse matrices, there is a dimension mismatch error. 但是当涉及稀疏矩阵时,存在尺寸不匹配误差。

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]

Output: 输出:

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

There is a function for sparse multiplication, eg, a.multiply(a[1]) for a * a[1] (which does its job perfectly), but I couldn't find one for addition. 有一个稀疏乘法的函数,例如a * a[1] a.multiply(a[1]) (完美地完成它的工作),但是我找不到一个用于加法的函数。

I'm new to sparse matrices. 我是稀疏矩阵的新手。 Please help. 请帮忙。

numpy style broadcasting has not been implemented for sparse matrices. 稀疏矩阵尚未实现numpy样式广播。

Multiplication, especially matrix multiplication, is well developed. 乘法,尤其是矩阵乘法,已得到很好的发展。 In fact actions like row sum and selection of rows are implemented as matrix multiplications - eg M * <column vector of 1s> . 实际上,诸如行和和行的选择之类的动作被实现为矩阵乘法 - 例如M * <column vector of 1s> Multiplication often results in a matrix that's as sparse if not more so. 乘法通常会产生一个稀疏的矩阵,如果不是这样的话。

Addition/subtraction is not well developed. 加法/减法没有很好地发展。 It often results in a denser matrix. 它通常会导致更密集的矩阵。 The extreme case is adding a scalar to all elements. 极端情况是为所有元素添加标量。 Even in your example, the result is dense. 即使在您的示例中,结果也很密集。 Both a and a[1,:] have to be quite sparse to justify a pure sparse addition. 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>

We can replicate the selected row by matrix multiplication - first the broadcasted dense approach: 我们可以通过矩阵乘法复制所选行 - 首先是广播密集方法:

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

sparse matrix multiplication: 稀疏矩阵乘法:

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>

sparse matrix addition: 稀疏矩阵加法:

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

This would be a better demonstration if aM and especially aM[1:] was sparse. 如果aM尤其是aM[1:]稀疏,这将是一个更好的示范。 I could also have specified the np.ones as int dtype to match aM . 我也可以将np.ones指定为int np.ones以匹配aM And making it a csc matrix would be more compact. 并使其成为csc矩阵将更紧凑。

Try with: 试试:

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

it will be: 这将是:

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

Update: 更新:

Make the addition matrix b with same dimension and full with a[1] , then add them: 使用a[1]使加法矩阵b具有相同的尺寸和满,然后添加它们:

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

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

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