Cómo eliminar elementos específicos en una matriz numpy

¿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 del a. Todo lo que sé es el índice de los valores (index=[2,3,6]).

preguntado el 12 de junio de 12 a las 12:06

12 Respuestas

Utiliza numpy.delete() - devuelve un Un nuevo matriz con sub-matrices 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 desde escalares de 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 el delete() documentos:

"A copia de arr con los elementos especificados por obj eliminados. Tenga en cuenta que la eliminación no se produce en el lugar... "

Si el código que publico tiene salida, es el resultado de ejecutar el código.

Respondido el 16 de junio de 16 a las 21:06

@IngviGautsson Cuando realizó su edición, también cambió los valores correctos para los elementos de 2, 3, 6 a 3, 4, 7, si ejecuta el código ahora, no obtendrá el resultado correcto como era originalmente. "Estoy retrocediendo la edición - Levon

AttributeError: el objeto 'lista' no tiene atributo 'eliminar' - munmunbb

@IngviGautsson No, su comentario es engañoso. Esto funciona como se esperaba. Sin embargo, la documentación de numpy.delete() señala que "a menudo es preferible usar una máscara booleana"; también se da un ejemplo de eso. - grande

@Levon, ¿puede agregar ejemplos para 2D? - MateS

@IngviGautsson Estás equivocado. Se necesitan los índices de los elementos para eliminar, no los elementos en sí. - la frite

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])

Respondido 06 Abr '16, 20:04

Bueno saber. Estaba pensando que np.delete sería más lento pero, lamentablemente, timeit para 1000 enteros dice que delete es x2 más rápido. - wbg

Esto es genial porque opera en la matriz valores en lugar de tener que proporcionar el índice o los índices que desea eliminar. Por ejemplo: np.setdiff1d(np.array(['one','two']),np.array(['two', 'three'])) - MD004

Esto también ordena la salida, que puede no ser lo que se desea. Por lo demás muy agradable. - Rayzinnz

La pregunta dice "Todo lo que sé es el índice de los valores". Entonces, se trata de eliminar elementos por sus índices, no eliminando con sus valores - Scott

Una matriz Numpy es inmutable, lo que significa que técnicamente no puede eliminar un elemento de él. Sin embargo, puede construir un Un nuevo matriz sin los valores que no desea, así:

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

Respondido el 12 de junio de 12 a las 13:06

+1 por mencionar 'inmutable'. Es bueno recordar que las matrices numpy no son buenas para cambios rápidos de tamaño (agregar/eliminar elementos) - eumiro

técnicamente, las matrices numpy SON mutables. Por ejemplo, esto: a[0]=1 modifica a en su lugar. Pero no se pueden cambiar de tamaño. - btel

La definición dice que es inmutable, pero si al asignar un nuevo valor te permite modificar, ¿cómo es inmutable? - Devesh

Para eliminar por valor:

modified_array = np.delete(original_array, np.where(original_array == value_to_delete))

Respondido 26 Abr '19, 10:04

La pregunta es sobre eliminar elementos por índices, sin eliminar elementos con un valor específico - Scott

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 la matriz usando una máscara booleana creada con la ayuda de np.isin. Este método nos permite eliminar los elementos especificándolos directamente o por 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)]

Quitar por elementos (no te olvides de recrear 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)]

Respondido 04 Abr '20, 07:04

No siendo una persona adormecida, 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é sería así?

Aún más extraño, pasando 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 grandes arreglos, 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í.

Respondido el 12 de junio de 12 a las 13:06

¡Cuidado con lo que realmente comparas! Tienes a = delte_stuff(a) en su primera iteración, lo que hace a más pequeño con cada iteración. Cuando usa la función inbuild, no almacena el valor nuevamente en a, ¡lo que mantiene a a en el tamaño original! Además de eso, puede acelerar su función drásticamente, cuando crea un conjunto de index y verifique contra eso, si eliminar o no un elemento. Al arreglar ambas cosas, obtengo 10k elementos: 6.22 mseg por bucle con su función, 4.48 mseg para numpy.delete, que es más o menos lo que cabría esperar. - Michael

Dos pistas más: en lugar de np.array(list(range(x))) utilizado np.arange(x), y para crear el índice, puede usar np.s_[::2]. - Michael

En caso de que no tenga los índices de los elementos que desea eliminar, puede usar la función in1d proporcionado por numpy.

La función regresa True si el elemento de una matriz 1-D también está presente en una segunda matriz. Para eliminar los elementos, solo tiene que negar los valores devueltos por esta función.

Note que este método mantiene el orden de la matriz original.

In [1]: import numpy as np

        a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
        rm = np.array([3, 4, 7])
        # np.in1d return true if the element of `a` is in `rm`
        idx = np.in1d(a, rm)
        idx

Out[1]: array([False, False,  True,  True, False, False,  True, False, False])

In [2]: # Since we want the opposite of what `in1d` gives us, 
        # you just have to negate the returned value
        a[~idx]

Out[2]: array([1, 2, 5, 6, 8, 9])

Respondido 16 Oct 20, 14:10

Si no conoce el índice, no puede usar logical_and

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

respondido 22 nov., 17:05

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]])

Respondido 21 Jul 19, 13:07

la comprensión de listas también podría ser un enfoque interesante.

a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
index = np.array([2, 3, 6]) #index is changed to an array.  
out = [val for i, val in enumerate(a) if all(i != index)]
>>> [1, 2, 5, 6, 8, 9]

Respondido el 02 de Septiembre de 20 a las 21:09

También puedes usar conjuntos:

a = numpy.array([10, 20, 30, 40, 50, 60, 70, 80, 90])
the_index_list = [2, 3, 6]

the_big_set = set(numpy.arange(len(a)))
the_small_set = set(the_index_list)
the_delta_row_list = list(the_big_set - the_small_set)

a = a[the_delta_row_list]

Respondido el 25 de Septiembre de 19 a las 15:09

Filtra la pieza que no necesitas:

import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
a = a[(a!=3)&(a!=4)&(a!=7)]

Si tiene una lista de índices para eliminar:

to_be_removed_inds = [2,3,6]
a = np.array([1,2,3,4,5,6,7,8,9])
a = a[[x for x in range(len(a)) if x not in to_be_removed]]

Respondido 25 Oct 21, 09:10

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.