Как сложить разреженные строки матрицы в первом столбце и обнулить остальные столбцы, с такими же размерами исходной матрицы? - PullRequest
0 голосов
/ 02 мая 2020

У меня есть разреженная матрица B, я хочу получить разреженную матрицу A из B суммированием всех строк в первом столбце, затем разделить первый столбец на '2' и сделать остальные столбцы нулевыми.

from numpy import array
from scipy import csr_matrix

row = array([0,0,1,2,2,2])
col = array([0,2,2,0,1,2])
data = array([1,2,3,4,5,6])

B = csr_matrix( (data,(row,col)), shape=(3,3) )

A = B.copy()

A = A.sum(axis=1)/2
# A shape becomes 1 x 3 instead of 3 x 3 here!

Ответы [ 2 ]

1 голос
/ 02 мая 2020

Я думаю, что к этому можно подойти несколькими способами. С вами все в порядке.

In [275]: from scipy.sparse import csr_matrix 
     ...:  
     ...: row = np.array([0,0,1,2,2,2]) 
     ...: col = np.array([0,2,2,0,1,2]) 
     ...: data = np.array([1,2,3,4,5,6.])    # make float 
     ...:  
     ...: B = csr_matrix( (data,(row,col)), shape=(3,3) )                                              
In [276]: A = B.copy()                                                                                 
In [277]: A                                                                                            
Out[277]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>'
    with 6 stored elements in Compressed Sparse Row format>

Назначение работает:

In [278]: A[:,0]  = A.sum(axis=1)/2                                                                    
/usr/local/lib/python3.6/dist-packages/scipy/sparse/_index.py:126: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  self._set_arrayXarray(i, j, x)
In [279]: A[:,1:] = 0                                                                                  
/usr/local/lib/python3.6/dist-packages/scipy/sparse/_index.py:126: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  self._set_arrayXarray(i, j, x)
In [280]: A                                                                                            
Out[280]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>'
    with 9 stored elements in Compressed Sparse Row format>

In [283]: A.eliminate_zeros()                                                                          
In [284]: A                                                                                            
Out[284]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>'
    with 3 stored elements in Compressed Sparse Row format>
In [285]: A.A                                                                                          
Out[285]: 
array([[1.5, 0. , 0. ],
       [1.5, 0. , 0. ],
       [7.5, 0. , 0. ]])

Предупреждение об эффективности в основном предназначено для предотвращения повторных или повторных назначений. Я думаю, что для одноразовых действий, подобных этому, их можно игнорировать.

Или если мы начнем с нуля A:

In [286]: A = csr_matrix(np.zeros(B.shape))   # may be better method                                                         
In [287]: A[:,0]  = B.sum(axis=1)/2                                                                    
/usr/local/lib/python3.6/dist-packages/scipy/sparse/_index.py:126: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  self._set_arrayXarray(i, j, x)
In [288]: A                                                                                            
Out[288]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>'
    with 3 stored elements in Compressed Sparse Row format>

В качестве альтернативы, матрица сумм столбцов может быть используется для непосредственного построения A, используя тот же стиль ввода, который использовался для определения B:

In [289]: A1  = B.sum(axis=1)/2                                                                        
In [290]: A1                                                                                           
Out[290]: 
matrix([[1.5],
        [1.5],
        [7.5]])
In [296]: row = np.arange(3)                                                                           
In [297]: col = np.zeros(3,int)                                                                        
In [298]: data = A1.A1                                                                                 
In [299]: A = csr_matrix((data, (row, col)), shape=(3,3))                                              
In [301]: A                                                                                            
Out[301]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>'
    with 3 stored elements in Compressed Sparse Row format>
In [302]: A.A                                                                                          
Out[302]: 
array([[1.5, 0. , 0. ],
       [1.5, 0. , 0. ],
       [7.5, 0. , 0. ]])

Я не знаю, какой подход наиболее быстрый. Ваш sparse.hstack выглядит хорошо, хотя под прикрытием hstack создает массивы row,col,data из форматов coo и создает новый coo_matrix. Несмотря на то, что он надежен, он не особенно оптимизирован.

0 голосов
/ 02 мая 2020

Ответ:

from numpy import array
from scipy import csr_matrix

row = array([0,0,1,2,2,2])
col = array([0,2,2,0,1,2])
data = array([1,2,3,4,5,6])

B = csr_matrix( (data,(row,col)), shape=(3,3) )

B_C = B.copy()
column1 = B_C.sum(axis=1)/2
#------------------------------------------------
columns = csr_matrix((B.shape[0],B.shape[1]-1))
A = sparse.hstack((column1 , columns ))
#------------------------------------------------
...