2010-03-03 12 views

risposta

7

Ho desiderato questo da solo e in realtà non esiste ancora un modo per farlo. Ecco un modo per farlo. Ho scelto di creare una sottoclasse di lil_matrix e di aggiungere la funzione remove_col. Se lo desideri, puoi invece aggiungere la funzione removecol alla classe lil_matrix nel tuo file lib/site-packages/scipy/sparse/lil.py. Ecco il codice:

from scipy import sparse 
from bisect import bisect_left 

class lil2(sparse.lil_matrix): 
    def removecol(self,j): 
     if j < 0: 
      j += self.shape[1] 

     if j < 0 or j >= self.shape[1]: 
      raise IndexError('column index out of bounds') 

     rows = self.rows 
     data = self.data 
     for i in xrange(self.shape[0]): 
      pos = bisect_left(rows[i], j) 
      if pos == len(rows[i]): 
       continue 
      elif rows[i][pos] == j: 
       rows[i].pop(pos) 
       data[i].pop(pos) 
       if pos == len(rows[i]): 
        continue 
      for pos2 in xrange(pos,len(rows[i])): 
       rows[i][pos2] -= 1 

     self._shape = (self._shape[0],self._shape[1]-1) 

Ho provato e non vedo alcun bug. Penso certamente che sia meglio che tagliare la colonna, che crea una nuova matrice per quanto ne so.

ho deciso di fare una funzione RemoveRow pure, ma non credo che sia buono come removecol. Sono limitato dal fatto di non essere in grado di rimuovere una riga da un narray nel modo che desidero. Ecco RemoveRow che può essere aggiunto alla classe

def removerow(self,i): 
     if i < 0: 
      i += self.shape[0] 

     if i < 0 or i >= self.shape[0]: 
      raise IndexError('row index out of bounds') 

     self.rows = numpy.delete(self.rows,i,0) 
     self.data = numpy.delete(self.data,i,0) 
     self._shape = (self._shape[0]-1,self.shape[1]) 

sopra Forse dovrei presentare queste funzioni al repository SciPy.

0

def removecols(W, col_list): 
     if min(col_list) = W.shape[1]: 
       raise IndexError('column index out of bounds') 
     rows = W.rows 
     data = W.data 
     for i in xrange(M.shape[0]): 
      for j in col_list: 
       pos = bisect_left(rows[i], j) 
       if pos == len(rows[i]): 
         continue 
       elif rows[i][pos] == j: 
         rows[i].pop(pos) 
         data[i].pop(pos) 
         if pos == len(rows[i]): 
           continue 
       for pos2 in xrange(pos,len(rows[i])): 
         rows[i][pos2] -= 1 
     W._shape = (W._shape[0], W._shape[1]-len(col_list)) 
     return W 

Basta riscritto il codice per lavorare con col_list come ingresso - forse questo sarà utile per qualcuno.

+1

Sono contento che qualcuno stia cercando di migliorare il mio primo tentativo. Tuttavia, la riga 'if min (col_list) = W.shape [1]:' non ha senso per me in molti modi. Innanzitutto, la sintassi non valida utilizza un assegnamento in un argomento if in Python. Secondo, perché stai controllando il minimo di col_list con la forma? Sto pensando che forse hai intenzione di fare 'if max (col_list)> = W.shape [1]:'? Ovviamente, ciò significa che non è possibile utilizzare anche gli indici negativi e non ci sono controlli per gli indici inferiori a 0 e che cosa fare con essi. –

1

Sono nuovo di python quindi la mia risposta è probabilmente sbagliato, ma mi chiedevo perché qualcosa di simile a quanto segue non sarà efficace?

permette di dire la tua lil_matrix si chiama tappeto e che si desidera rimuovere la colonna i-esima:

mat=hstack([ mat[:,0:i] , mat[:,i+1:] ]) 

Ora la matrice si trasformi in un coo_matrix dopo che, ma si può girare di nuovo a lil_matrix.

Ok, ho capito che questo dovrà creare le due matrici all'interno dello hstack prima di assegnarlo alla variabile mat quindi sarebbe come avere la matrice originale più una allo stesso tempo ma suppongo che se la la scarsità è abbastanza grande quindi penso che non ci dovrebbero essere problemi di memoria (poiché la memoria (e il tempo) è l'intera ragione dell'uso di matrici sparse).

+0

Sembra una domanda, non una risposta. –

8

Molto più semplice e veloce. Potresti anche non aver bisogno della conversione in csr, ma so per certo che funziona con matrici sparse csr e la conversione tra non dovrebbe essere un problema.

from scipy import sparse 

x_new = sparse.lil_matrix(sparse.csr_matrix(x)[:,col_list]) 
+0

Questo non funziona per me. – kevin

+2

Perché stai utilizzando la matrice CSR (compressa a righe sparse) per l'affettatura di colonne? Uno degli svantaggi del formato CSR è "operazioni lente di segmentazione delle colonne (considera CSC)" (in base ai documenti scipy). Probabilmente dovresti usare la conversione 'csc_matrix'. – silentser

1

Per una matrice sparsa CSR (X) e un elenco di indici di goccia (index_to_drop):

to_keep = list(set(xrange(X.shape[1]))-set(index_to_drop))  
new_X = X[:,to_keep] 

È facile convertire lil_matrices a csr_matrices. Controllare tocsr() in lil_matrix documentation

Nota tuttavia che passare da matrici csr a lil usando tolil() è costoso. Quindi, questa scelta è buona quando non è necessario avere la matrice in formato lil.

0

Osservando le note per ogni matrice sparsa, in particolare nel nostro caso è matrice CSC ha i seguenti vantaggi elencati nella documentazione [1]

  • operazioni aritmetiche efficienti CSC + CSC, CSC * CSC, ecc .
  • efficiente colonna affettare
  • prodotti vettoriali matrici veloce (CSR, BSR può essere più veloce)

Se si dispone gli indici delle colonne si WA nt per rimuovere, basta usare affettare. Per rimuovere le righe utilizzare la matrice csr poiché è efficiente nell'affrontare righe

Problemi correlati