Разреженная матрица: удаление строк, если их сумма меньше X (Сципи) - PullRequest
1 голос
/ 23 апреля 2020

Допустим, у меня есть следующая разреженная матрица:

from scipy.sparse import coo_matrix
m = coo_matrix(([1,1,1,3,2], ([1,2,2,3,4],[1,1,2,3,3])))
print(m.toarray())

>>> array([[0, 0, 0, 0],
>>>       [0, 1, 0, 0],
>>>       [0, 1, 1, 0],
>>>       [0, 0, 0, 3],
>>>       [0, 0, 0, 2]])

И я хочу сохранить только те строки, сумма которых больше 1. Я думал, что будет работать следующее.

csr = m.tocsr()
csr[(csr.sum(1) > 1)]

Но это не так. Вместо этого мне пришлось сделать преобразование в массив numpy (используя squeeze):

csr = m.tocsr()
csr = csr[np.asarray(csr.sum(1) > 1).squeeze()]
csr.toarray()

Итак, я получаю то, что хочу:

array([[0, 1, 1, 0],
       [0, 0, 0, 3],
       [0, 0, 0, 2]], dtype=int64)

Есть ли еще простой способ сделать это?

Я знаю, что есть похожие ответы, например, после проверки некоторых других ответов, таких как этот , но в их случае (с M.getnnz(1)>0) функция возвращает массив непосредственно.

1 Ответ

2 голосов
/ 23 апреля 2020

Посмотрите детали:

In [803]: m = sparse.csr_matrix(([1,1,1,3,2], ([1,2,2,3,4],[1,1,2,3,3])))                              
In [804]: m                                                                                            
Out[804]: 
<5x4 sparse matrix of type '<class 'numpy.longlong'>'
    with 5 stored elements in Compressed Sparse Row format>
In [805]: m.A                                                                                          
Out[805]: 
array([[0, 0, 0, 0],
       [0, 1, 0, 0],
       [0, 1, 1, 0],
       [0, 0, 0, 3],
       [0, 0, 0, 2]], dtype=int64)
In [806]: m.sum(axis=1)                                                                                
Out[806]: 
matrix([[0],
        [1],
        [2],
        [3],
        [2]])

sum на ndarray уменьшает размеры (если не установлено keepdims). Но sparse копирует np.matrix и сохраняет размеры. Таким образом, результатом является (5,1) матрица.

np.matrix имеет сокращение для шага array/ravel:

In [807]: m.sum(axis=1).A1                                                                             
Out[807]: array([0, 1, 2, 3, 2])

И индексирование:

In [811]: m[m.sum(axis=1).A1>1,:]                                                                      
Out[811]: 
<3x4 sparse matrix of type '<class 'numpy.longlong'>'
    with 4 stored elements in Compressed Sparse Row format>
In [812]: _.A                                                                                          
Out[812]: 
array([[0, 1, 1, 0],
       [0, 0, 0, 3],
       [0, 0, 0, 2]], dtype=int64)

Я упоминал в другом месте, что csr матричная индексация (обычно) использует «матрицу экстрактора» и умножение матриц. Это надежный и разумный способ хранения данных, но он не такой быстрый и мощный, как плотная индексация массива.

Иногда мы набираем скорость, воздействуя на базовые атрибуты матрицы, data indices и indptr. Но это требует большего понимания этого представления, поэтому я не буду go вдаваться в детали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...