将Rowsum列添加到大型稀疏矩阵

时间:2020-02-09 00:44:34

标签: python numpy scikit-learn scipy

我有一个大的稀疏矩阵X(2百万行,23k cols),我想在上面添加一个rowum列并返回一个稀疏矩阵。

我在下面尝试过

np.hstack( (X.toarray(),X.sum(axis=1)) )

,但不适用于大型稀疏矩阵。

问题是,当我调用X.toarray()时,它爆炸并终止python内核,而没有给出任何错误消息。

我尝试过的Sil

sparse.hstack( X ,sparse.csr_matrix(X.sum(axis=1)))
sparse.csr_matrix(X.sum(axis=1)).ndim    # is 2
X.ndim # 2 as well

但是它给了我下面的错误信息:

~/miniconda3/lib/python3.7/site-packages/scipy/sparse/construct.py in bmat(blocks, format, dtype)
    546 
    547     if blocks.ndim != 2:
--> 548         raise ValueError('blocks must be 2-D')
    549 
    550     M,N = blocks.shape

ValueError: blocks must be 2-D

有什么办法可以解决此问题?

2 个答案:

答案 0 :(得分:2)

In [93]: from scipy import sparse                                                              
In [94]: M = sparse.random(5,7, .2, 'csr')                                                     
In [95]: M                                                                                     
Out[95]: 
<5x7 sparse matrix of type '<class 'numpy.float64'>'
    with 7 stored elements in Compressed Sparse Row format>

一个总和是(n,1)np.matrix

In [96]: M.sum(axis=1)                                                                         
Out[96]: 
matrix([[0.92949904],
        [1.068337  ],
        [0.10927561],
        [0.        ],
        [0.68352182]])

另一个(1,n)矩阵:

In [97]: M.sum(axis=0)                                                                         
Out[97]: 
matrix([[0.        , 0.90221854, 0.42335774, 1.35578158, 0.        ,
         0.        , 0.10927561]])

将列添加到矩阵(注意参数详细信息):

In [98]: sparse.hstack((M, M.sum(axis=1)))                                                     
Out[98]: 
<5x8 sparse matrix of type '<class 'numpy.float64'>'
    with 11 stored elements in COOrdinate format>

添加行矩阵:

In [99]: sparse.vstack((M, M.sum(axis=0)))                                                     
Out[99]: 
<6x7 sparse matrix of type '<class 'numpy.float64'>'
    with 11 stored elements in COOrdinate format>

答案 1 :(得分:1)

一种可能的解决方法是像这样使用矩阵乘法。

首先来看一个小例子,看看发生了什么。 x是一个辅助矩阵,yy将与您的数据相对应:

>>> K,N,D = 5,10,3
>>> 
>>> x = sparse.csc_matrix((np.ones(2*K),np.r_[np.arange(K),np.arange(K)],np.r_[np.arange(K+1),2*K]),(K,K+1))
>>> 
>>> x.A
array([[1., 0., 0., 0., 0., 1.],
       [0., 1., 0., 0., 0., 1.],
       [0., 0., 1., 0., 0., 1.],
       [0., 0., 0., 1., 0., 1.],
       [0., 0., 0., 0., 1., 1.]])
>>> 
>>> y = np.random.randint(0,N,(D,K))
>>> y.sort(0)
>>> yy = sparse.csc_matrix((np.ones(D*K),y.ravel(),np.arange(K+1)*D),(N,K))
>>> 
>>> yy.A
array([[1., 0., 0., 0., 0.],
       [2., 1., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 1., 1., 1., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 1.],
       [0., 0., 0., 0., 0.],
       [0., 0., 2., 1., 0.],
       [0., 0., 0., 1., 1.],
       [0., 0., 0., 0., 1.]])
>>> 
>>> (yy@x).A
array([[1., 0., 0., 0., 0., 1.],
       [2., 1., 0., 0., 0., 3.],
       [0., 1., 0., 0., 0., 1.],
       [0., 1., 1., 1., 0., 3.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 1., 1.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 2., 1., 0., 3.],
       [0., 0., 0., 1., 1., 2.],
       [0., 0., 0., 0., 1., 1.]])

还有一个显示比例的更大示例:

>>> K,N,D = 23_000,2_000_000,100
>>> 
>>> x = sparse.csc_matrix((np.ones(2*K),np.r_[np.arange(K),np.arange(K)],np.r_[np.arange(K+1),2*K]),(K,K+1))
>>> x
<23000x23001 sparse matrix of type '<class 'numpy.float64'>'
        with 46000 stored elements in Compressed Sparse Column format>
>>> 
>>> y = np.random.randint(0,N,(D,K))
>>> y.sort(0)
>>> yy = sparse.csc_matrix((np.ones(D*K),y.ravel(),np.arange(K+1)*D),(N,K))
>>> yy
<2000000x23000 sparse matrix of type '<class 'numpy.float64'>'
        with 2300000 stored elements in Compressed Sparse Column format>
>>> 
>>> yy@x
<2000000x23001 sparse matrix of type '<class 'numpy.float64'>'
        with 3667102 stored elements in Compressed Sparse Column format>