2012-06-12 17 views

risposta

160

Usa numpy.delete() - restituisce un nuovo gamma con sub-array lungo un asse cancellato

numpy.delete(a, index) 

Per la vostra domanda specifica:

import numpy as np 

a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]) 
index = [2, 3, 6] 

new_a = np.delete(a, index) 

print(new_a) #Prints `[1, 2, 5, 6, 8, 9]` 

Nota che numpy.delete() restituisce un nuovo array dal array scalars sono immutabile, simile alle stringhe in Python, quindi ogni volta che viene apportata una modifica, viene creato un nuovo oggetto. Vale a dire, per citare il delete()docs:

"A copy of arr with the elements specified by obj removed. Note that delete does not occur in-place..."

Se il codice che ho post è uscita, è il risultato della esecuzione del codice.

+1

Grazie mille. Ho provato che Bur non poteva farlo funzionare per qualche motivo. Funziona ora –

+0

@DanielThaagaardAndreasen Felice di essere stato in grado di aiutare. – Levon

+1

Questa risposta è fuorviante. Il secondo argomento di numpy.delete non è un indice dell'elemento che si desidera rimuovere, ma l'elemento effettivo che si desidera rimuovere. –

29

Un array Numpy è immutable, il che significa che tecnicamente non è possibile eliminare un elemento da esso. Tuttavia, è possibile costruire una nuova gammasenza i valori che non si desidera, in questo modo:

b = np.delete(a, [2,3,6]) 
+0

Grazie per la tua risposta –

+0

+1 per menzionare 'immutabile' E 'bene ricordare, che gli array NumPy non sono buone per un rapido cambiamenti di dimensioni (aggiunta/eliminazione di elementi) – eumiro

+20

tecnicamente, gli array di numpy SONO mutabili.Ad esempio, questo: 'a [0] = 1' modifica' a' in luogo, ma non possono essere ridimensionati – btel

4

Non essendo una persona NumPy, ho preso un colpo con:

>>> import numpy as np 
>>> import itertools 
>>> 
>>> a = np.array([1,2,3,4,5,6,7,8,9]) 
>>> index=[2,3,6] 
>>> a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))]))) 
>>> a 
array([1, 2, 5, 6, 8, 9]) 

Secondo i miei test, questo sovraperforma numpy.delete(). Non so perché sarebbe il caso, forse a causa delle piccole dimensioni della matrice iniziale?

python -m timeit -s "import numpy as np" -s "import itertools" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))" 
100000 loops, best of 3: 12.9 usec per loop 

python -m timeit -s "import numpy as np" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "np.delete(a, index)" 
10000 loops, best of 3: 108 usec per loop 

Questa è una differenza piuttosto significativo (in direzione opposta a quello che mi aspettavo), qualcuno ha qualche idea del perché questo sarebbe il caso?

Ancora più stranamente, passando a numpy.delete() un elenco si comporta in modo peggiore di un ciclo attraverso l'elenco e dandogli singoli indici.

python -m timeit -s "import numpy as np" -s "a = np.array([1,2,3,4,5,6,7,8,9])" -s "index=[2,3,6]" "for i in index:" " np.delete(a, i)" 
10000 loops, best of 3: 33.8 usec per loop 

Modifica: sembra avere a che fare con la dimensione dell'array. Con array di grandi dimensioni, numpy.delete() è notevolmente più veloce.

python -m timeit -s "import numpy as np" -s "import itertools" -s "a = np.array(list(range(10000)))" -s "index=[i for i in range(10000) if i % 2 == 0]" "a = np.array(list(itertools.compress(a, [i not in index for i in range(len(a))])))" 
10 loops, best of 3: 200 msec per loop 

python -m timeit -s "import numpy as np" -s "a = np.array(list(range(10000)))" -s "index=[i for i in range(10000) if i % 2 == 0]" "np.delete(a, index)" 
1000 loops, best of 3: 1.68 msec per loop 

Ovviamente, questo è tutto abbastanza irrilevante, come si dovrebbe sempre andare per la chiarezza ed evitare di reinventare la ruota, ma ho trovato un po 'interessante, quindi ho pensato di lasciarla qui.

+2

Stai attento a ciò che effettivamente comparato! Hai 'a = delte_stuff (a)' nella tua prima iterazione, il che rende 'a' più piccolo ad ogni iterazione. Quando usi la funzione inbuild, non riporti il ​​valore su a, che mantiene un in la dimensione originale! Bes Ciò significa che puoi accelerare drasticamente la tua funzione quando crei un set di 'index' e verifica se eliminare o meno un elemento. Risolvendo entrambe le cose, ottengo 10k articoli: 6,22 msec per ciclo con la funzione, 4,48 msec per 'numpy.delete', che è approssimativamente come ci si aspetterebbe. – Michael

+2

Altri due suggerimenti: invece di 'np.array (lista (intervallo (x)))' usa 'np.arange (x)', e per creare l'indice, puoi usare 'np.s _ [:: 2]' . – Michael

25

C'è una funzione incorporata numpy per aiutare con quello.

import numpy as np 
>>> a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]) 
>>> b = np.array([3,4,7]) 
>>> c = np.setdiff1d(a,b) 
>>> c 
array([1, 2, 5, 6, 8, 9]) 
+2

Buono a sapersi. Stavo pensando che np.delete sarebbe più lento ma ahimè, timeit per 1000 interi dice che l'eliminazione è x2 più veloce. – wbg

0

Se non si conosce l'indice, non è possibile utilizzare logical_and

x = 10*np.random.randn(1,100) 
low = 5 
high = 27 
x[0,np.logical_and(x[0,:]>low,x[0,:]<high)]