web-dev-qa-db-fra.com

Existe-t-il un moyen efficace de concaténer les matrices scipy.sparse?

Je travaille avec des matrices clairsemées plutôt grandes (de 5000x5000 à 20000x20000) et j'ai besoin de trouver un moyen efficace de concaténer des matrices de manière flexible afin de construire une matrice stochastique à partir de parties séparées.

En ce moment, j'utilise la manière suivante pour concaténer quatre matrices, mais c'est horriblement inefficace. Y a-t-il une meilleure façon de faire cela qui n'implique pas la conversion en une matrice dense?

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

La bibliothèque clairsemée a désormais hstack et vstack pour concaténer respectivement les matrices horizontalement et verticalement.

49
Erik

D'accord, j'ai trouvé la réponse. L'utilisation de scipy.sparse.coo_matrix est beaucoup plus rapide que l'utilisation de lil_matrix. J'ai converti les matrices en COO (indolore et rapide), puis j'ai simplement concaténé les données, les lignes et les colonnes après avoir ajouté le bon remplissage.

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

La réponse d'Amos n'est plus nécessaire. Scipy fait maintenant quelque chose de similaire en interne si les matrices d'entrée sont au format csr ou csc et que le format de sortie souhaité est défini sur aucun ou le même format que les matrices d'entrée. Il est efficace d'empiler verticalement des matrices au format csr, ou d'empiler horizontalement des matrices au format csc, en utilisant scipy.sparse.vstack ou scipy.sparse.hstack, respectivement.

13
Joel Croteau

L'utilisation de hstack, vstack ou concatenate est considérablement plus lente que la concaténation des objets de données internes eux-mêmes. La raison en est que hstack/vstack convertit la matrice clairsemée au format coo qui peut être très lent lorsque la matrice n'est pas très grande et pas au format coo. Voici le code de concaténation des matrices csc, une méthode similaire peut être utilisée pour les 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))
11
Amos