Есть ли эффективный способ объединения матриц scipy.sparse? - PullRequest
34 голосов
/ 27 июля 2011

Я работаю с некоторыми довольно большими разреженными матрицами (от 5000x5000 до 20000x20000) и мне нужно найти эффективный способ гибкого объединения матриц для построения стохастической матрицы из отдельных частей.

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

rmat[0:m1.shape[0],0:m1.shape[1]] = m1
rmat[m1.shape[0]:rmat.shape[0],m1.shape[1]:rmat.shape[1]] = m2
rmat[0:m1.shape[0],m1.shape[1]:rmat.shape[1]] = bridge
rmat[m1.shape[0]:rmat.shape[0],0:m1.shape[1]] = bridge.transpose()

Ответы [ 4 ]

49 голосов
/ 11 мая 2012

В разреженной библиотеке теперь есть hstack и vstack для соответственного объединения матриц по горизонтали и вертикали.

14 голосов
/ 28 июля 2011

Хорошо, я нашел ответ.Использование scipy.sparse.coo_matrix намного быстрее, чем использование lil_matrix.Я преобразовал матрицы в coo (безболезненно и быстро), а затем просто добавил данные, строки и столбцы после добавления правильного заполнения.

data = scipy.concatenate((m1S.data,bridgeS.data,bridgeTS.data,m2S.data))
rows = scipy.concatenate((m1S.row,bridgeS.row,bridgeTS.row + m1S.shape[0],m2S.row + m1S.shape[0]))
cols = scipy.concatenate((m1S.col,bridgeS.col+ m1S.shape[1],bridgeTS.col ,m2S.col + m1S.shape[1])) 

scipy.sparse.coo_matrix((data,(rows,cols)),shape=(m1S.shape[0]+m2S.shape[0],m1S.shape[1]+m2S.shape[1]) )
13 голосов
/ 01 сентября 2017

Ответ Амоса больше не нужен. Scipy теперь делает что-то похожее на это внутри, если входные матрицы имеют формат csr или csc, а желаемый выходной формат не установлен или совпадает с форматом входных матриц. Эффективно составлять матрицы по вертикали в формате csr или по горизонтали укладывать матрицы в формате csc, используя scipy.sparse.vstack или scipy.sparse.hstack соответственно.

11 голосов
/ 21 октября 2015

Использование hstack, vstack или сцепления значительно медленнее, чем конкатенация самих внутренних объектов данных. Причина в том, что hstack / vstack преобразует разреженную матрицу в формат coo, который может быть очень медленным, если матрица очень большая, а не в формате coo. Вот код для конкатенации матриц csc, аналогичный метод можно использовать для матриц csr:

def concatenate_csc_matrices_by_columns(matrix1, matrix2):
    new_data = np.concatenate((matrix1.data, matrix2.data))
    new_indices = np.concatenate((matrix1.indices, matrix2.indices))
    new_ind_ptr = matrix2.indptr + len(matrix1.data)
    new_ind_ptr = new_ind_ptr[1:]
    new_ind_ptr = np.concatenate((matrix1.indptr, new_ind_ptr))

    return csc_matrix((new_data, new_indices, new_ind_ptr))
...