У меня есть разреженная матрица в формате csr, например:
>>> a = sp.random(3, 3, 0.6, format='csr') # an example
>>> a.toarray() # just to see how it looks like
array([[0.31975333, 0.88437035, 0. ],
[0. , 0. , 0. ],
[0.14013856, 0.56245834, 0.62107962]])
>>> a.data # data array
array([0.31975333, 0.88437035, 0.14013856, 0.56245834, 0.62107962])
Для этого конкретного примера я хочу получить [0, 4]
, которые являются индексами массива данных ненулевых диагональных элементов 0.31975333
и 0.62107962
.
Простой способ сделать это заключается в следующем:
ind = []
seen = set()
for i, val in enumerate(a.data):
if val in a.diagonal() and val not in seen:
ind.append(i)
seen.add(val)
Но на практике матрица очень большая, поэтому я не хочу использоватьдля циклов или преобразовать в массив Numpy, используя метод toarray()
.Есть ли более эффективный способ сделать это?
Редактировать : Я только что понял, что приведенный выше код дает неверный результат в случаях, когда есть недиагональные элементы, равные и предшествующие некоторым издиагональные элементы: возвращает индексы этого недиагонального элемента.Также он не возвращает индексы повторяющихся диагональных элементов.Например:
a = np.array([[0.31975333, 0.88437035, 0. ],
[0.62107962, 0.31975333, 0. ],
[0.14013856, 0.56245834, 0.62107962]])
a = sp.csr_matrix(a)
>>> a.data
array([0.31975333, 0.88437035, 0.62107962, 0.31975333, 0.14013856,
0.56245834, 0.62107962])
Мой код возвращает ind = [0, 2]
, но должно быть [0, 3, 6]
.Код, предоставленный Андрасом Диком (его функция get_rowwise
), возвращает правильный результат.