2011-07-27 11 views
26

Estoy trabajando con matrices dispersas bastante grandes (de 5000x5000 a 20000x20000) y necesito encontrar una forma eficiente de concatenar matrices de forma flexible para construir una matriz estocástica a partir de partes separadas.¿Hay una manera eficiente de concatenar matrices scipy.sparse?

En este momento estoy usando la siguiente forma para concatenar cuatro matrices, pero es terriblemente ineficiente. ¿Hay alguna forma mejor de hacer esto que no implique convertir 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() 

Respuesta

14

Bien, encontré la respuesta. Usar scipy.sparse.coo_matrix es mucho más rápido que usar lil_matrix. Convertí las matrices en coo (indoloras y rápidas) y luego concatenamos 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])) 
+1

Gracias por volver y comentando cómo lo hizo rápidamente. Lo necesitaba para mi clase NLP. – placeybordeaux

42

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

+1

Asegúrese de utilizar scipy.sparse.hstack en lugar de numpy.hstack – 0111001101110000

9

Usar hstack, vstack o concatenar es mucho más lento que concatenar los objetos de datos internos. La razón es que hstack/vstack convierte la matriz dispersa en formato coo, que puede ser muy lenta cuando la matriz es muy grande y no está en formato coo. Aquí está el código para la concatenación de matrices csc, método similar se puede utilizar para matrices RSE:

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)) 
+1

Estaba simplemente buscando una manera rápida de agregar nuevas filas a una matriz de CSR. Esto es exactamente lo que necesito. Gracias @amos. – singleton

+0

Si utiliza este método, debe especificar la forma en 'return csc_matrix ((new_data, new_indices, new_ind_ptr))', es decir: 'return csc_matrix ((new_data, new_indices, new_ind_ptr), shape = (matrix1.shape [1], matrix1.shape [1] + matrix2.shape [1]) ' – simeon

4

respuesta de Amos ya no es necesario. Ahora, Scipy hace algo similar a esto internamente si las matrices de entrada están en formato csr o csc y ​​el formato de salida deseado está configurado en ninguno o en el mismo formato que las matrices de entrada. Es eficiente para apilar verticalmente matrices en formato RSE, o horizontalmente matrices pila en formato csc, utilizando scipy.sparse.vstack o scipy.sparse.hstack, respectivamente.

+0

¿A qué versión se refiere "ahora"? ¿Tiene alguna referencia para esto? – lenz

+0

El código relevante es [este fragmento] (https://github.com /scipy/scipy/blob/master/scipy/sparse/construct.py#L552) a partir de 'scipy.sparse.bmat', que tanto' vstack' y 'uso hstack' Este truco se añadió originalmente [aquí] (https.: //github.com/scipy/scipy/commit/10b2cbdc980c6e1695c732c90fba99f722437171) en 2013. Parece que originalmente se incluyó en scipy 1.0.0. –

+0

¡Gracias! Scipy 1.0.0 todavía está en la etapa RC, aunque ... – lenz

Cuestiones relacionadas