2012-11-23 12 views
5

Numpy gamma ammette un elenco di indici, ad esempiofetta multipla nella lista di indicizzazione per NumPy serie

a = np.arange(1000) 
l = list([1,44,66,33,90,345]) 
a[l] = 22 

Ma questo metodo non funziona se vogliamo usare un multiplo indicizzazione fetta o indici oltre a una fetta, per esempio.

a = np.arange(1000) 
l = list([1,44,66,33,90, slice(200,300) , slice(500,600) ]) 
a[l] = 22 

Questo codice restituisce un messaggio di errore:

IndexError: too many indices 

La mia domanda è molto semplice: fai a sapere se in NumPy o SciPy esiste un metodo efficiente per l'utilizzo di questo tipo di indicizzazione?

O che cosa è un modo buono ed efficiente per l'utilizzo di un metodo di indicizzazione come questo?

Non dimenticare che l'uso di fette di produrre un codice molto veloce; e il mio problema è avere il codice più veloce possibile.

+0

Aiuta a sapere come si passa attraverso questo. Che cosa sai in anticipo e cosa sai solo per iterazione? Quali altri vincoli ci sono sul problema? –

risposta

4

quello che viene in mente:

a = np.arange(1000) 
l = np.hstack(([1, 44, 66, 33, 90], np.arange(200, 300), np.arange(500, 600))) 
a[l] = 22 

non sono sicuro se è il modo più semplice, ma funziona.

Modifica: hai ragione che questo è più lento rispetto all'utilizzo di fette; ma non puoi creare un oggetto fetta con valori arbitrari. Forse dovresti fare diverse assegnazioni poi:

%timeit a[np.hstack(([1, 44, 66, 33, 90], np.arange(200, 300), np.arange(500, 600)))] = 22 
10000 loops, best of 3: 39.5 us per loop 

%timeit a[[1, 44, 66, 33, 90]] = 22; a[200:300] = 22; a[500:600] = 22 
100000 loops, best of 3: 18.4 us per loop 
+0

Ma questo metodo non usa le slice, che sono molto veloci rispetto all'indicizzazione dell'array. Funziona ma non è efficiente. – Giggi

+0

@Giggi True; modificato. Non so se c'è un modo per ottenere quello che vuoi, però. –

0

È possibile utilizzare l'indicizzazione di fantasia per costruire un elenco di indice.

l = numpy.array([1,44,66,33,90]+range(200,300)+range(500,600)) 
a[l] = 22 

Ma, come @Lev sottolineato, questo non può essere più veloce (anche se quasi certamente sarà se si può precompute la lista degli indici).

Tuttavia, l'indicizzazione di fantasia si applica per asse. Quindi puoi inventare l'indice su un asse e affettare gli altri, se questo ti aiuta per niente:

a = numpy.random.randn(4, 5, 6) 
l = numpy.array([1, 2]) 
a[l, slice(None), slice(2, 4)] = 10 
Problemi correlati