¿Hay alguna manera de eliminar los elementos específicos de una matriz numpy “in situ” en python:

Al llamar a “np.delete ()”, no me interesa definir una nueva variable para la matriz de tamaño reducido. Quiero ejecutar la eliminación en la matriz numpy original. ¿Cualquier pensamiento?

>>> arr = np.array([[1,2], [5,6], [9,10]]) >>> arr array([[ 1, 2], [ 5, 6], [ 9, 10]]) >>> np.delete(arr, 1, 0) array([[ 1, 2], [ 9, 10]]) >>> arr array([[ 1, 2], [ 5, 6], [ 9, 10]]) but I want: >>> arr array([[ 1, 2], [ 9, 10]]) 

Los arreglos de NumPy son de tamaño fijo, por lo que no puede haber una versión local de np.delete . Cualquier función de este tipo tendría que cambiar el tamaño de la matriz.

Lo más cercano que puedes conseguir es reasignar la variable arr :

 arr = numpy.delete(arr, 1, 0) 

La llamada de delete no modifica la matriz original, la copia y devuelve la copia después de que se realiza la eliminación.

 >>> arr1 = np.array([[1,2], [5,6], [9,10]]) >>> arr2 = np.delete(arr, 1, 0) >>> arr1 array([[ 1, 2], [ 5, 6], [ 9, 10]]) >>> arr2 array([[ 1, 2], [ 9, 10]]) 

Si es una cuestión de rendimiento, es posible que desee probar ( pero probarlo ya que no estoy seguro ) creando una vista * en lugar de usar np.delete . Puede hacerlo cortando, lo que debería ser una operación in situ :

 import numpy as np arr = np.array([[1, 2], [5, 6], [9, 10]]) arr = arr[(0, 2), :] print(arr) 

Resultando en:

 [[ 1 2] [ 9 10]] 

Esto, sin embargo, no liberará la memoria ocupada de la fila excluida. Puede boost el rendimiento, pero la memoria podría tener el mismo o peor problema. También tenga en cuenta que, por lo que sé, no hay manera de indexar por exclusión (por ejemplo, arr[~1] sería muy útil), lo que necesariamente hará que invierta recursos en la creación de una matriz de indexación.

Para la mayoría de los casos, creo que la sugerencia que otros usuarios han dado, a saber:

 arr = numpy.delete(arr, 1, 0) 

, es la mejor. En algunos casos podría valer la pena explorar la otra alternativa.

EDIT: * Esto es realmente incorrecto (gracias @ user2357112). La indexación sofisticada no crea una vista, sino que devuelve una copia como se puede ver en la documentación (que debería haber revisado antes de sacar conclusiones, lamento eso):

 Advanced indexing always returns a copy of the data (contrast with basic slicing that returns a view). 

Como tal, no estoy seguro de si la sugerencia de indexación elegante valga algo como una sugerencia real a menos que tenga algún aumento de rendimiento en comparación con el método np.delete (que intentaré verificar cuando surja la oportunidad, consulte EDIT2 ).

EDIT2: realicé una prueba muy simple para ver si hay alguna ganancia de rendimiento al usar la indexación de fantasía por oposición para eliminar la función. Se utilizó timeit (en realidad, la primera vez que lo he usado, pero parece que el número de ejecuciones por fragmento de código es de 1 000 000, por lo tanto, los números más altos para el tiempo):

 import numpy as np import timeit def test1(): arr = np.array([[1, 2], [5, 6], [9, 10]]) arr = arr[(0, 2), :] def test2(): arr = np.array([[1, 2], [5, 6], [9, 10]]) arr = np.delete(arr, 1, 0) print("Equality test: ", test1() == test2()) print(timeit.timeit("test1()", setup="from __main__ import test1")) print(timeit.timeit("test2()", setup="from __main__ import test2")) 

Los resultados son estos:

 Equality test: True 5.43569152576767 9.476918448174644 

Lo que representa una ganancia de velocidad muy considerable. Sin embargo, tenga en cuenta que la creación de la secuencia para la indexación de fantasía llevará tiempo. Si vale la pena o no dependerá seguramente del problema a resolver.

Podría implementar su propia versión de delete que copia elementos de datos después de los elementos que se van a eliminar hacia adelante, y luego devuelve una vista que excluye el último elemento (ahora obsoleto):

 import numpy as np # in-place delete def np_delete(arr, obj, axis=None): # this is a only simplified example assert (isinstance(obj, int)) assert (axis is None) for i in range(obj + 1, arr.size): arr[i - 1] = arr[i] return arr[:-1] Test = 10 * np.arange(10) print(Test) deleteIndex = 5 print(np.delete(Test, deleteIndex)) print(np_delete(Test, deleteIndex)) 

No hay nada malo en tu código. solo tienes que override la variable

  arr = np.array([[1,2], [5,6], [9,10]]) arr = np.delete(arr, 1, 0)