Подтвердить что ты не робот

Есть ли эффективный способ конкатенации матриц scipy.sparse?

Я работаю с довольно крупными разреженными матрицами (от 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()
4b9b3361

Ответ 1

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

Ответ 2

Хорошо, я нашел ответ. Использование 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]) )

Ответ 3

Использование hstack, vstack или concatenate значительно медленнее, чем конкатенирование самих внутренних объектов данных. Причина в том, что 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))

Ответ 4

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