2012-05-19 13 views
10

Qual è il modo migliore per rimuovere in modo efficiente le colonne da una matrice sparsa che contiene solo zeri. Ho una matrice che ho creato e riempito con i dati:Come rimuovere in modo efficiente le colonne da una matrice sparsa che contiene solo zeri?

matrix = sp.sparse.lil_matrix((100, 100)) 

desidero ora per rimuovere ~ ultimi 20 colonne che contengono solo i dati a zero. Come posso fare questo?

+3

Siete impegnati ad usare lil_matrix? Secondo i documenti scipy, non è efficiente per l'affettamento di colonne - si potrebbe invece prendere in considerazione csc_matrix. Vedi: http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.lil_matrix.html e http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse. csc_matrix.html –

+0

Grazie per l'aiuto. Sì, csr o csc va bene anche. – turtle

+0

@turtle ha risposto alla tua domanda? – gabe

risposta

8

Se questo fosse solo un allineamento NumPy, X, allora si potrebbe dire X!=0 che darebbe un allineamento booleano della stessa forma X , e quindi si potrebbe indice X con l'array booleano, vale a dire non_zero_entries = X[X!=0]

Ma questa è una matrice sparsa che non supporta l'indicizzazione booleano e, inoltre, non vi darà ciò che vuoi se si tenta X!=0 - si restituisce solo un cantare il valore booleano che sembra restituire true solo se sono esattamente la stessa matrice (in memoria).

Quello che vuoi è il metodo nonzero da numpy.

import numpy as np 
from scipy import sparse 

X = sparse.lil_matrix((100,100)) # some sparse matrix 
X[1,17] = 1 
X[17,17] = 1 
indices = np.nonzero(X) # a tuple of two arrays: 0th is row indices, 1st is cols 
X.tocsc()[indices] # this just gives you the array of all non-zero entries 

Se si desidera solo le colonne complete dove ci sono voci diverse da zero, basta prendere il primo dagli indici. Tranne che è necessario tenere conto di indici ripetuti (se ci sono più di uno voci in una colonna):

columns_non_unique = indices[1] 
unique_columns = sorted(set(columns_non_unique)) 
X.tocsc()[:,unique_columns] 
+3

Ho usato quanto segue per estrarre solo le colonne con voci diverse da zero: 'matrix [:, np.unique (alldata.nonzero() [1])]' – canzar

+0

Questo è bello e compatto. Più o meno lo stesso, eccetto che usi numpy's unique invece di 'sorted (set (columns))'. – gabe

+1

per essere chiari, la maggior parte delle matrici sparse ha un metodo '.nonzero' che funziona allo stesso modo e molto più velocemente di' np.nonzero (sparse_matrix) '. Risposta utile comunque. –

1

Questo appare come la strada, anche se non idealmente efficiente:

matrix = matrix[0:100,0:80] 
+0

Sfortunatamente, il numero di colonne pari a zero non è sempre corretto. Ho bisogno di un modo per farlo in modo che se ci fossero 35 colonne zero o 10 colonne zero il programma funzionerebbe ancora. – turtle

0

Si può anche usare scipy.sparse.find() per ottenere le posizioni di tutti gli elementi diversi da zero nella matrice sparsa.

La voce [1] th nel valore restituito è una serie numerica di numeri di colonna. Prendendo i valori univoci da questa matrice si forniscono gli indici delle colonne diverse da zero. La suddivisione della matrice sparsa originale con queste colonne ci fornisce le colonne diverse da zero.

x[:,np.unique(sparse.find(x)[1])] 

Si può estendere questo per trovare le colonne con almeno n voci:

idx = np.unique(sparse.find(x)[1], return_counts=True) 
x[:, idx[0][idx[1] > n]] 
Problemi correlati