Добавление столбца суммы строк в большую разреженную матрицу - PullRequest
0 голосов
/ 09 февраля 2020

У меня большая разреженная матрица X (2 мил строки, 23k столбцов), и я хотел бы добавить к ней столбец строки и вернуть разреженную матрицу.

Я пробовал ниже

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

, но это не работает с большой разреженной матрицей.

Дело в том, что когда я вызываю X.toarray(), он взрывается и завершает работу python ядра без сообщения об ошибке.

Похоже, я пытался

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 ]

2 голосов
/ 09 февраля 2020
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]])

Другая матрица a (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 голос
/ 09 февраля 2020

Одним из возможных путей решения проблемы может быть использование умножения матриц следующим образом.

Сначала небольшой пример, чтобы увидеть, что происходит. 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...