¿Existe una forma eficiente de concatenar matrices scipy.sparse?

Estoy trabajando con algunas matrices dispersas bastante grandes (de 5000×5000 a 20000×20000) y necesito encontrar una forma eficiente de concatenar matrices de una manera flexible para construir una matriz estocástica a partir de partes separadas.

Ahora mismo estoy usando la siguiente forma de concatenar cuatro matrices, pero es horriblemente ineficiente. ¿Hay alguna forma mejor de hacer esto que no implique la conversión a una matriz densa?

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() 

La biblioteca dispersa ahora tiene hstack y vstack para concatenar matrices horizontal y verticalmente, respectivamente.

Está bien, he encontrado la respuesta. Usar scipy.sparse.coo_matrix es mucho más rápido que usar lil_matrix. Convertí las matrices a coo (indoloro y rápido) y luego concatené los datos, filas y columnas después de agregar el relleno correcto.

 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]) ) 

La respuesta de Amos ya no es necesaria. Scipy ahora hace algo similar a esto internamente si las matrices de entrada están en formato csr o csc y ​​el formato de salida deseado se establece en ninguno o el mismo formato que las matrices de entrada. Es eficiente astackr verticalmente matrices en formato csr, o astackr horizontalmente matrices en formato csc, usando scipy.sparse.vstack o scipy.sparse.hstack , respectivamente.

El uso de hstack, vstack o concatenate es mucho más lento que concatenar los objetos de datos internos. La razón es que hstack / vstack convierte la matriz dispersa al formato de coo, que puede ser muy lento cuando la matriz no es muy grande y no está en formato de coo. Aquí está el código para concatenar matrices csc, se puede usar un método similar para las matrices 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))