Установить несколько строк и столбцов большой скудной разреженной матрицы в 0 с - PullRequest
0 голосов
/ 08 мая 2018

Я пытаюсь "перевести" некоторый код Matlab в Python, и в Matlab есть одна строка, которая устанавливает несколько строк в разреженной матрице в 0s:

Ks(idx,:)=0; %no affinity for W inside fs

где Ks - это разреженная матрица (которая является симметричной и имеет довольно большой размер), а idx - это одномерный массив, обозначающий индексы строк для внесения изменений, а также довольно большой по размеру. И в следующей строке он также меняет эти столбцы на 0, поэтому Ks все еще симметричен:

Ks(:,idx)=0;

Подобные действия в Python (Ks[idx,:]=0), похоже, работают только для маленьких матриц, когда они становятся большими, я получаю MemoryError. В настоящее время моя Ks является матрицей csr, преобразующей ее в lil и делающей это очень медленно.

Я не совсем знаком с разреженными матрицами, я знаю, что в Python есть более 1 типа (например, csr, csc, lil и т. Д.), Но в коде Matlab нет таких различий, я только нашел вызов функции sparse(). Так, какова моя лучшая ставка в этой ситуации?

Заранее спасибо.

1 Ответ

0 голосов
/ 08 мая 2018

Один из способов ускорения состоит в том, чтобы вместо установки элементов разреженной матрицы на ноль, сначала установить элементы массива numpy nd в ноль, а затем преобразовать в разреженную матрицу. Я получил повышение скорости более чем в 10 раз в приведенном ниже примере.

import numpy as np
import scipy.sparse as sps
np.random.seed(20)
mat = np.random.randint(-2000,2000,size=(1000,1000))
sym_mat = (mat + mat.T)/2

zero_rows =  np.random.randint(0,999,(900,))


%%timeit
sparse = sps.csr_matrix(sym_mat)
sparse[zero_rows,:] = 0
sparse[:,zero_rows] = 0

/usr/local/lib/python3.6/dist-packages/scipy/sparse/compressed.py:774: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient.
  SparseEfficiencyWarning)
1 loop, best of 3: 206 ms per loop

%%timeit
sym_mat[zero_rows,:] = 0
sym_mat[:,zero_rows] = 0
sparse1 = sps.csr_matrix(sym_mat)

100 loops, best of 3: 18.9 ms per loop
...