2012-11-12 4 views
16

SciPy Sparse Matrix tutorial è molto buono - ma in realtà lascia la sezione su slicing un (der) sviluppato (ancora in forma di contorno - vedere la sezione: "Gestione di matrici sparse").Affettare le matrici sparse in Scipy - Quali tipi funzionano meglio?

Proverò ad aggiornare il tutorial, una volta che questa domanda avrà risposta.

Ho una matrice sparse di grandi dimensioni - attualmente in formato dok_matrix.

import numpy as np 
from scipy import sparse 
M = sparse.dok_matrix((10**6, 10**6)) 

Per vari metodi che voglio essere in grado di tagliare le colonne e per gli altri che voglio affettare righe. Idealmente mi usare advanced-indicizzatore (cioè un vettore booleano, bool_vect) con cui affettare una matrice sparsa M - come in:

bool_vect = np.arange(10**6)%2 # every even index 
out = M[bool_vect,:]   # Want to select every even row 

o

out = M[:,bool_vect] # Want to select every even column 

Innanzitutto, dok_matrices non supportano questo - ma penso che funzioni (lentamente) se prima getto a lil_matrices, via sparse.lil_matrix(M)

Per quanto posso raccogliere dal tutorial - per tagliare le colonne voglio usare CSC e per tagliare le righe che voglio tagliare CSR. Quindi significa che dovrei lanciare la matrice M via:

M.tocsc()[:,bool_vect] 

o

M.tocsr()[bool_vect,:] 

sto genere di indovinare qui e il mio codice è lento a causa di esso. Qualsiasi aiuto da parte di qualcuno che capisca come funziona sarebbe apprezzato. Grazie in anticipo.

Se risulta che non dovrei indicizzare la mia matrice con un array booleano, ma piuttosto un elenco di numeri interi (indici), è anche qualcosa che sarei felice di scoprire. Qualunque sia più efficiente.

Infine - questa è una grande matrice, quindi punti bonus se questo può accadere sul posto/con trasmissione.

risposta

31

Ok, quindi sono abbastanza sicuro che il modo "giusto" per farlo è: se si stanno affettando le colonne, usare tocsc() e tagliare usando una lista/matrice di numeri interi. I vettori booleani non sembrano fare il trucco con matrici sparse - come fa con ndarrays in numpy. Il che significa che la risposta è.

indices = np.where(bool_vect)[0] 
out1 = M.tocsc()[:,indices] 
out2 = M.tocsr()[indices,:] 

Ma domanda: è questo il modo migliore? È a posto?

In pratica questo sembra accadere sul posto - ed è molto più veloce dei tentativi precedenti (usando lil_matrix).

+0

Se 'M' è un formato che non ha indicizzazione (' coo' o 'dok'), allora questa conversione è la strada giusta. Ma se 'M' è già' csr' il passaggio a 'csc' solo per fare l'indicizzazione delle colonne potrebbe non valerne la pena. L'indicizzazione 'sparse' è un business complicato. – hpaulj