2013-11-01 29 views
8

Dato un grande array 2d numpy, vorrei rimuovere un intervallo di righe, ad esempio righe 10000:10010 in modo efficiente. Devo farlo più volte con intervalli diversi, quindi mi piacerebbe anche renderlo parallelizzabile.Come si può rimuovere in modo efficiente un intervallo di righe da un grande array numpy?

L'utilizzo di qualcosa come numpy.delete() non è efficiente, poiché è necessario copiare l'array, richiedendo troppo tempo e memoria. Idealmente, vorrei fare qualcosa come creare una vista, ma non sono sicuro di come potrei farlo in questo caso. Anche un array mascherato non è un'opzione in quanto le operazioni downstream non sono supportate su array mascherati.

Qualche idea?

+1

Quali sono le operazioni a valle? Potresti cercare di falsificare la cancellazione tenendo traccia delle righe da eliminare ... – Jaime

risposta

3

A causa della struttura di dati stridulo che definisce una matrice numpy, ciò che si desidera non sarà possibile senza utilizzare un array mascherato. L'opzione migliore potrebbe essere quella di utilizzare un array mascherato (o forse il proprio array booleano) per mascherare le righe eliminate e quindi eseguire un'unica operazione reale delete di tutte le righe da eliminare prima di passarla a valle.

+0

Grazie, ho il sospetto che non ci sia modo di aggirare questo problema (ma vediamo se qualcuno presenta una soluzione creativa). Non capisco però perché hai proposto di mascherare e poi cancellare - come è meglio che cancellare? – Bitwise

+1

Questo è in parte un'ipotesi su come il tuo codice che capirà cosa eliminare dovrà funzionare. Come hai sottolineato, l'eliminazione ripetuta di righe di righe sarà inefficiente (in termini di memoria e tempo). Inoltre, ho interpretato "Devo farlo più volte con intervalli diversi" come la parte che potrebbe essere parallelizzabile. Per farlo in parallelo, ti consigliamo di mantenere invariato l'array sottostante, e basta semplicemente capovolgere i bit "cancellati" appropriati. Quindi, una volta individuate tutte le righe da eliminare, è possibile eseguire la vera operazione di "eliminazione" nel passaggio finale non parallelo. –

2

Non c'è davvero un buon modo per velocizzare l'operazione di cancellazione, come già accennato, questo tipo di cancellazione richiede che i dati vengano copiati in memoria. L'unica cosa che puoi fare, come suggerito da @WarrenWeckesser, è combinare più operazioni di cancellazione e applicarle tutte contemporaneamente. Ecco un esempio:

ranges = [(10, 20), (25, 30), (50, 100)] 
mask = np.ones(len(array), dtype=bool) 

# Update the mask with all the rows you want to delete 
for start, end in ranges: 
    mask[start:stop] = False 

# Apply all the changes at once 
new_array = array[mask] 

Non ha molto senso per parallelizzare questo perché si sta solo copiando roba in memoria in modo tale sarà la memoria legato in ogni modo, l'aggiunta di più CPU non aiuterà.

0

Non so quanto sia veloce, rispetto a quanto sopra, ma diciamo che hai una lista L di indici di riga delle righe che vuoi mantenere dall'array A (per "righe" intendo il primo indice, per matrici dimensionali superiori). Tutte le altre righe saranno cancellate. Lasceremo A mantenere il risultato.

A = A[np.ix_(L)] 
Problemi correlati