¿Cómo puedo eliminar algunos elementos específicos de una matriz numpy? Di que tengo
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
Entonces quiero eliminar 3,4,7
de a
. Todo lo que sé es el índice de los valores ( index=[2,3,6]
).
¿Cómo puedo eliminar algunos elementos específicos de una matriz numpy? Di que tengo
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
Entonces quiero eliminar 3,4,7
de a
. Todo lo que sé es el índice de los valores ( index=[2,3,6]
).
Respuestas:
Use numpy.delete () : devuelve una nueva matriz con submatrices a lo largo de un eje eliminado
numpy.delete(a, index)
Para su pregunta específica:
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]`
Tenga en cuenta que numpy.delete()
devuelve una nueva matriz, ya que los escalares de la matriz son inmutables, similares a las cadenas en Python, por lo que cada vez que se realiza un cambio, se crea un nuevo objeto. Es decir, para citar los delete()
documentos :
"Una copia de arr con los elementos especificados por obj eliminados. Tenga en cuenta que la eliminación no ocurre en el lugar ..."
Si el código que publico tiene salida, es el resultado de ejecutar el código.
Hay una función incorporada numpy para ayudar con eso.
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']))
Una matriz de Numpy es inmutable , lo que significa que técnicamente no puede eliminar un elemento de ella. Sin embargo, puede construir una nueva matriz sin los valores que no desea, como este:
b = np.delete(a, [2,3,6])
a[0]=1
modifica a
en su lugar. Pero no pueden ser redimensionados.
Para eliminar por valor:
modified_array = np.delete(original_array, np.where(original_array == value_to_delete))
No siendo una persona numpy, tomé 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])
Según mis pruebas, esto supera numpy.delete()
. No sé por qué ese sería el caso, ¿tal vez debido al pequeño tamaño de la matriz inicial?
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
Esa es una diferencia bastante significativa (en la dirección opuesta a lo que esperaba), ¿alguien tiene alguna idea de por qué este sería el caso?
Aún más extraño, pasar numpy.delete()
una lista funciona peor que recorrer la lista y darle índices únicos.
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
Editar: parece tener que ver con el tamaño de la matriz. Con matrices grandes, numpy.delete()
es significativamente más rápido.
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
Obviamente, todo esto es bastante irrelevante, ya que siempre debes buscar claridad y evitar reinventar la rueda, pero lo encontré un poco interesante, así que pensé en dejarlo aquí.
a = delte_stuff(a)
en tu primera iteración, que se hace a
más pequeña con cada iteración. Cuando usa la función inbuild, no almacena el valor de nuevo en a, lo que mantiene a en el tamaño original. Además de eso, puede acelerar su función drásticamente, cuando crea un conjunto index
y comprueba si se elimina o no un elemento. Arreglando ambas cosas, obtengo 10k artículos: 6.22 ms por bucle con su función, 4.48 ms por numpy.delete
, que es aproximadamente lo que esperaría.
np.array(list(range(x)))
usar np.arange(x)
, y para crear el índice, puede usar np.s_[::2]
.
Usar np.delete
es la forma más rápida de hacerlo, si conocemos los índices de los elementos que queremos eliminar. Sin embargo, para completar, permítanme agregar otra forma de "eliminar" elementos de matriz usando una máscara booleana creada con la ayuda de np.isin
. Este método nos permite eliminar los elementos al especificarlos directamente o mediante sus índices:
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
Eliminar por índices :
indices_to_remove = [2, 3, 6]
a = a[~np.isin(np.arange(a.size), indices_to_remove)]
Eliminar por elementos (no olvide volver a crear el original a
ya que fue reescrito en la línea anterior):
elements_to_remove = a[indices_to_remove] # [3, 4, 7]
a = a[~np.isin(a, elements_to_remove)]
Eliminar índice específico (eliminé 16 y 21 de la matriz)
import numpy as np
mat = np.arange(12,26)
a = [4,9]
del_map = np.delete(mat, a)
del_map.reshape(3,4)
Salida:
array([[12, 13, 14, 15],
[17, 18, 19, 20],
[22, 23, 24, 25]])