У меня есть куча данных в формате SciPy compressed sparse row (CSR). Конечно, большинство элементов равно нулю, и я также знаю, что все ненулевые элементы имеют значение 1. Я хочу вычислить суммы по различным подмножествам строк моей матрицы. На данный момент я делаю следующее:Эффективно вычислять столбцовую сумму разреженного массива, где каждый ненулевой элемент равен 1
import numpy as np
import scipy as sp
import scipy.sparse
# create some data with sparsely distributed ones
data = np.random.choice((0, 1), size=(1000, 2000), p=(0.95, 0.05))
data = sp.sparse.csr_matrix(data, dtype='int8')
# generate column-wise sums over random subsets of rows
nrand = 1000
for k in range(nrand):
inds = np.random.choice(data.shape[0], size=100, replace=False)
# 60% of time is spent here
extracted_rows = data[inds]
# 20% of time is spent here
row_sum = extracted_rows.sum(axis=0)
Последние нескольких строк есть узкое место в большем вычислительном трубопроводе. Как я отметил в коде, 60% времени потрачено нарезание данных из случайных индексов, а 20% потрачено на вычисление фактической суммы.
Мне кажется, что я должен использовать свои знания о данных в массиве (т. Е. Любое ненулевое значение в разреженной матрице будет равно 1, других значений нет) для более эффективного вычисления этих сумм. К сожалению, я не могу понять, как это сделать. Возможно, только с data.indices
? Я пробовал другие структуры разреженности (например, CSC-матрицу), а также сначала преобразовывался в плотный массив, но эти подходы были все медленнее, чем этот матричный подход CSR.
Вот две функции, которые могут вам пригодиться: 'rows, cols = extract_rows.nonzero()', который дает вам индексы ненулевых компонентов и, возможно, 'np.count_nonzero()', который подсчитывает ненулевые записи в numb array – benbo