Come posso rimuovere alcuni elementi specifici da una matrice numpy? Di 'che ho
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
Voglio quindi rimuovere 3,4,7
da a
. Tutto quello che so è l'indice dei valori ( index=[2,3,6]
).
Come posso rimuovere alcuni elementi specifici da una matrice numpy? Di 'che ho
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
Voglio quindi rimuovere 3,4,7
da a
. Tutto quello che so è l'indice dei valori ( index=[2,3,6]
).
Risposte:
Usa numpy.delete () - restituisce un nuovo array con sotto-array lungo un asse eliminato
numpy.delete(a, index)
Per la tua 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]`
Si noti che numpy.delete()
restituisce un nuovo array poiché gli scalari di array sono immutabili, simili alle stringhe in Python, quindi ogni volta che viene apportata una modifica ad esso, viene creato un nuovo oggetto. Vale a dire, per citare i delete()
documenti :
"Una copia di arr con gli elementi specificati da obj rimossi. Nota che la cancellazione non avviene sul posto ..."
Se il codice che invio ha un output, è il risultato dell'esecuzione del codice.
C'è una funzione incorporata intorpidita 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])
np.setdiff1d(np.array(['one','two']),np.array(['two', 'three']))
Un array Numpy è immutabile , il che significa che tecnicamente non è possibile eliminare un elemento da esso. Tuttavia, puoi costruire un nuovo array senza i valori che non desideri, in questo modo:
b = np.delete(a, [2,3,6])
a[0]=1
modifica a
sul posto. Ma non possono essere ridimensionati.
Per cancellare per valore:
modified_array = np.delete(original_array, np.where(original_array == value_to_delete))
Non essendo una persona insensibile, ho fatto una foto 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 supera numpy.delete()
. Non so perché sarebbe così, forse a causa delle piccole dimensioni dell'array 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 abbastanza significativa (nella direzione opposta a quella che mi aspettavo), qualcuno ha idea del perché questo sarebbe il caso?
Ancora più stranamente, il passaggio di numpy.delete()
un elenco ha prestazioni peggiori rispetto al passare in rassegna l'elenco e assegnandogli 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 le dimensioni dell'array. Con array di grandi dimensioni, numpy.delete()
è significativamente 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, tutto ciò è piuttosto irrilevante, poiché dovresti sempre andare per chiarezza ed evitare di reinventare la ruota, ma l'ho trovato un po 'interessante, quindi ho pensato di lasciarlo qui.
a = delte_stuff(a)
nella tua prima iterazione, che si a
riduce con ogni iterazione. Quando si utilizza la funzione inbuild, non si memorizza il valore in a, che mantiene a nella dimensione originale! Oltre a ciò, puoi velocizzare drasticamente la tua funzione, quando crei un set di index
e controlli contro quello, se eliminare o meno un elemento. Risolvendo entrambe le cose, ottengo 10k articoli: 6,22 msec per ciclo con la tua funzione, 4,48 msec per numpy.delete
, che è più o meno quello che ti aspetteresti.
np.array(list(range(x)))
utilizzare np.arange(x)
e per creare l'indice, è possibile utilizzare np.s_[::2]
.
L'utilizzo np.delete
è il modo più veloce per farlo, se conosciamo gli indici degli elementi che vogliamo rimuovere. Tuttavia, per completezza, vorrei aggiungere un altro modo di "rimuovere" gli elementi dell'array usando una maschera booleana creata con l'aiuto di np.isin
. Questo metodo ci consente di rimuovere gli elementi specificandoli direttamente o tramite i loro indici:
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
Rimuovi per indici :
indices_to_remove = [2, 3, 6]
a = a[~np.isin(np.arange(a.size), indices_to_remove)]
Rimuovi per elementi (non dimenticare di ricreare l'originale a
poiché è stato riscritto nella riga precedente):
elements_to_remove = a[indices_to_remove] # [3, 4, 7]
a = a[~np.isin(a, elements_to_remove)]
Rimuovi indice specifico (ho rimosso 16 e 21 dalla matrice)
import numpy as np
mat = np.arange(12,26)
a = [4,9]
del_map = np.delete(mat, a)
del_map.reshape(3,4)
Produzione:
array([[12, 13, 14, 15],
[17, 18, 19, 20],
[22, 23, 24, 25]])