2014-07-08 11 views
6

Ho una matrice numpy e una lista contenente un numero di oggetti fetta (in alternativa contenente tuple (start, end)). Sto cercando di rimuovere le posizioni dell'oggetto slice dall'array originale e ottenere un secondo array con i valori rimanenti. esempioEliminazione di più porzioni da una serie numpy

Toy:

myarray = np.arange(20) 

array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 
     17, 18, 19]) 

mylist=(slice(2,4),slice(15,19)) 

fare qualcosa e risultato dovrebbe essere

array([0, 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) 

L'array può essere in qualche centinaio di migliaia di grandi dimensioni, l'elenco degli oggetti porzione può contenere alcune migliaia di elementi e Ho bisogno di eseguire l'operazione spesso, quindi la velocità è un po 'importante.

Numpy delete non ha una lista di fette fino a che punto posso vedere?

Per ora sto generando il complemento della mia lista di oggetti fetta e affettandolo, ma la generazione del complemento è un processo un po 'scomodo in cui sto ordinando la mia lista di fette e iterando attraverso di essa, creando gli oggetti fetta complementare secondo necessità. Spero che ci sia un modo più elegante che non ho capito!

risposta

1

È possibile utilizzare set() per identificare quali posizioni saranno conservati e np.take() per ottenere corrispondenti valori, fare qualcosa come:

ind = np.indices(myarray.shape)[0] 
rm = np.hstack([ind[i] for i in mylist]) 

ans = np.take(myarray, sorted(set(ind)-set(rm))) 

noti che np.hstack() viene utilizzato per ottenere un singolo array con tutti gli indici che verrà essere rimosso. Questo richiede circa la metà del tempo della soluzione di @ HYRY.

+1

Ha funzionato alla grande, grazie! – anordell

1

Non riesco a pensare a un modo per unire le fette in modo pulito; comunque, penso che usare il composito sia la strada da percorrere. Forse provare qualcosa di simile:

import numpy as np 

# Create test data 
n_data = 1000000 
n_slices = 10000 

data = np.arange(n_data) 
slices = [] 
for i in range(n_slices): 
    r = np.random.randint(n_data-1000) 
    slices.append(slice(r,r + np.random.randint(1000))) 

# Remove slices 
keep_mask = np.ones_like(data, dtype=bool) 
for slice in slices: keep_mask[slice] = False 
data = data[keep_mask] # or np.take, etc. 
1

È possibile utilizzare np.r_[] per unire le fette in un array:

myarray = np.arange(20) 
mylist=(slice(2, 4),slice(15, 19)) 
np.delete(myarray, np.r_[tuple(mylist)]) 

uscita:

array([ 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 19]) 

Ma penso che non è molto veloce.