Supponiamo di avere una matrice NxN M (lil_matrix o csr_matrix) da scipy.sparse, e voglio renderla (N + 1) xN dove M_modified [i, j] = M [i, j] per 0 < = i < N (e tutto j) e M [N, j] = 0 per tutti i j. Fondamentalmente, voglio aggiungere una riga di zeri alla fine di M e conservare il resto della matrice. C'è un modo per farlo senza copiare i dati?espandendo (aggiungendo una riga o colonna) una matrice scipy.sparse
risposta
Non penso che esista un modo per sfuggire alla copia. Entrambi questi tipi di matrici sparse memorizzano i propri dati come array Numpy (negli attributi data e indici per csr e negli attributi data e rows per lil) internamente e gli array Numpy non possono essere estesi.
aggiornamento con ulteriori informazioni:
LIL fa riposare per lista collegata, ma l'implementazione corrente non abbastanza all'altezza del nome. Gli array Numpy utilizzati per data
e rows
sono entrambi di tipo oggetto. Ciascuno degli oggetti in questi array sono in realtà elenchi Python (una lista vuota quando tutti i valori sono pari a zero in una riga). Gli elenchi Python non sono esattamente elenchi collegati, ma sono piuttosto vicini e francamente una scelta migliore a causa della ricerca O (1). Personalmente, non vedo immediatamente il punto di usare una serie di oggetti Numpy qui piuttosto che una semplice lista Python. Potresti facilmente cambiare l'attuale implementazione di lil per usare invece gli elenchi Python che ti permetteranno di aggiungere una riga senza copiare l'intera matrice.
Non so se stai ancora cercando una soluzione, ma forse altri possono esaminare hstack
e vstack
- http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.hstack.html. Penso che possiamo definire una csr_matrix per l'unica riga aggiuntiva e quindi vstack
con la matrice precedente.
[codice sorgente per vstack] (https://github.com/scipy/scipy/blob/v0.19.0/scipy/sparse/construct.py#L461-L492) Come questo implica, restituisce una nuova copia dell'input matrici, quindi non abbastanza efficienti se vogliamo espandere una matrice ** in place **. – JenkinsY
Scipy non ha un modo per farlo senza copiare i dati ma è possibile farlo da soli modificando gli attributi che definiscono la matrice sparsa.
Ci sono 4 attributi che compongono il csr_matrix:
dati: Un array contenente i valori effettivi nella matrice
indici: Un array che contiene l'indice di colonna corrispondente a ciascun valore nei dati
indptr: una matrice che specifica l'indice prima del primo valore nei dati per ogni riga. Se la riga è vuota, l'indice è uguale alla colonna precedente.
forma: una tupla contenente la forma della matrice
Se siete semplicemente aggiungendo una fila di zeri in fondo tutto ciò che dovete fare è cambiare la forma e indptr per la matrice.
x = np.ones((3,5))
x = csr_matrix(x)
x.toarray()
>> array([[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.]])
# reshape is not implemented for csr_matrix but you can cheat and do it yourself.
x._shape = (4,5)
# Update indptr to let it know we added a row with nothing in it. So just append the last
# value in indptr to the end.
# note that you are still copying the indptr array
x.indptr = np.hstack((x.indptr,x.indptr[-1]))
x.toarray()
array([[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 0., 0., 0., 0., 0.]])
Ecco una funzione per gestire il caso più generale di vstacking di 2 csr_matrices. Continuerai a copiare gli array numpy sottostanti, ma è ancora significativamente più veloce del metodo vstack scipy.
def csr_vappend(a,b):
""" Takes in 2 csr_matrices and appends the second one to the bottom of the first one.
Much faster than scipy.sparse.vstack but assumes the type to be csr and overwrites
the first matrix instead of copying it. The data, indices, and indptr still get copied."""
a.data = np.hstack((a.data,b.data))
a.indices = np.hstack((a.indices,b.indices))
a.indptr = np.hstack((a.indptr,(b.indptr + a.nnz)[1:]))
a._shape = (a.shape[0]+b.shape[0],b.shape[1])
return a
Penso che si possa fare a meno di non tornare 'a', poiché gli argomenti delle funzioni sono passati per riferimento,' a' viene modificato direttamente anche all'interno dell'ambito della funzione. Inoltre, può esistere un analogo csc_happend (a, b)? – richizy
Buona idea, per ripristinare semplicemente la forma. – Jan
- 1. Aggiunta colonna o riga in matrice 3D
- 2. Determinazione della dimensione in byte di una matrice scipy.sparse?
- 3. scipy.sparse: imposta la riga sugli zeri
- 4. Come anteporre una colonna a una matrice?
- 5. Ottieni una colonna diversa in ogni riga
- 6. Aggiungendo un elenco o una serie a un DataFrame panda come una riga?
- 7. Stampa di una matrice di array su una riga nella console (una riga per oggetto matrice matrice) in Ruby
- 8. Argmax di ogni riga o colonna nella matrice sparsa scipy
- 9. NSFetchedResultsController anteporre una riga o una sezione
- 10. Slickgrid aggiunge colore a una cella/colonna o riga
- 11. Creare una matrice "piramide"
- 12. PDOStatement PHP: Recupera una riga, come prima colonna come chiave di una matrice
- 13. Come posso recuperare una colonna di matrice e il nome di una riga con un valore di indice di matrice?
- 14. Moltiplica ciascuna colonna di una matrice con un'altra matrice
- 15. Come moltiplicare in modo elementare una matrice scipy.sparse con un array 1d denso trasmesso?
- 16. Determinazione dell'ultima riga in una singola colonna
- 17. Rcpp NumericMatrix - come cancellare una riga/colonna?
- 18. Come si estrae una colonna da una matrice multidimensionale?
- 19. Come si inserisce una riga/colonna in una griglia WPF?
- 20. Come aggiungere una matrice a una riga SQL in C#?
- 21. minimo di una matrice sparsa?
- 22. qual è il modo più veloce per inizializzare una matrice scipy.sparse con numpy.NaN?
- 23. Qual è il modo più veloce per tagliare una matrice scipy.sparse?
- 24. aggiungendo una nuova colonna al dataframe panda con valori per elementi particolari?
- 25. Java: come inizializzare una matrice in Java su una riga?
- 26. Come rimuovere una determinata riga o colonna durante l'utilizzo di Eigen Library C++
- 27. Applicare una funzione a ogni riga di una matrice o di un frame di dati
- 28. Come copiare una riga di QUALSIASI tabella cambiando una colonna
- 29. Seleziona una riga con valore distinto di una colonna
- 30. dividere una riga su 2 o più righe a seconda di una colonna di
Se è abbastanza fondamentale per la vostra applicazione, si potrebbe essere in grado di implementare una nuova classe con l'interfaccia scipy.sparse che utilizza un tipo di dati più facilmente estendibile sotto il cofano. –
Forse qualcuno più esperto sulla struttura dati sottostante potrebbe rispondere a questo. Pensavo che lil_matrix fosse implementato con liste collegate? – RandomGuy
@scandido, controlla se la mia ultima aggiunta risponde alla tua domanda. –