Разреженная матрица: как получить ненулевые индексы для каждой строки

У меня есть матрица Scipy CSR, и я хочу получить индексы столбцов элементов для каждой строки. Мой подход:

import scipy.sparse as sp
N = 100
d = 0.1
M = sp.rand(N, N, d, format='csr')

indM = [row.nonzero()[1] for row in M]

indM - это то, что мне нужно, он имеет то же количество строк, что и M, и выглядит так:

[array([ 6,  7, 11, ..., 79, 85, 86]),
 array([12, 20, 25, ..., 84, 93, 95]),
...
 array([ 7, 24, 32, 40, 50, 51, 57, 71, 74, 96]),
 array([ 1,  4,  9, ..., 71, 95, 96])]

Проблема в том, что с большими матрицами этот подход выглядит медленным. Есть ли способ избежать понимания списка или как-то ускорить это?

Спасибо.


person Alexey Trofimov    schedule 14.06.2017    source источник


Ответы (1)


Вы можете просто использовать атрибуты indices и indptr напрямую:

import numpy
import scipy.sparse

N = 5
d = 0.3
M = scipy.sparse.rand(N, N, d, format='csr')
M.toarray()
# array([[ 0.        ,  0.        ,  0.        ,  0.        ,  0.        ],
#        [ 0.        ,  0.        ,  0.        ,  0.        ,  0.30404632],
#        [ 0.63503713,  0.        ,  0.        ,  0.        ,  0.        ],
#        [ 0.68865311,  0.81492098,  0.        ,  0.        ,  0.        ],
#        [ 0.08984168,  0.87730292,  0.        ,  0.        ,  0.18609702]])

M.indices
# array([1, 2, 4, 3, 0, 1, 4], dtype=int32)
M.indptr
# array([0, 3, 4, 6, 6, 7], dtype=int32)

numpy.split(M.indices, M.indptr)[1:-1]
# [array([], dtype=int32),
#  array([4], dtype=int32),
#  array([0], dtype=int32),
#  array([0, 1], dtype=int32),
#  array([0, 1, 4], dtype=int32)]
person Nils Werner    schedule 14.06.2017
comment
M.tolil().rows дает объектный массив списков с одинаковыми значениями. - person hpaulj; 14.06.2017