2012-06-12 70 views

Respuesta

160

Uso numpy.delete() - devuelve una nueva gama con submatrices a lo largo de un eje elimina

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 array scalars son inmutable, similar a las cadenas en Python, por lo que cada vez que se realiza un cambio en él, se crea un nuevo objeto. Es decir, por citar el delete()docs:

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

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

+1

Muchas gracias. Intenté que la fresa no pudiera hacerlo funcionar por alguna razón. Funciona ahora –

+0

@DanielThaagaardAndreasen Feliz de haber podido ayudar. – Levon

+1

Esta respuesta es engañosa. El segundo argumento para numpy.delete no es un índice del artículo que desea eliminar, sino el elemento real que desea eliminar. –

29

Una matriz Numpy es immutable, lo que significa que técnicamente no puede eliminar un elemento de la misma. Sin embargo, se puede construir una nueva matrizsin los valores que no desea, de esta manera:

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

Gracias por su respuesta –

+0

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

+20

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

4

no ser 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 a 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 muy significativa (en el sentido contrario 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 al 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 que tiene que ver con el tamaño de la matriz. Con arreglos 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 hay que ir por la claridad y evitar reinventar la rueda, pero me pareció un poco interesante, así que pensé que me iría aquí.

+2

Tenga cuidado con lo que ¡realmente comparar! Usted tiene '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 de nuevo en a, que mantiene una el tamaño original! Bes Esto significa que puedes acelerar drásticamente tu función cuando creas un conjunto de 'índice' y verificas si eso elimina o no un elemento. Reparando ambas cosas, obtengo 10k artículos: 6.22 mseg por ciclo con su función, 4.48 mseg para 'numpy.delete', que es más o menos lo que usted esperaría. – Michael

+2

Dos consejos más: en lugar de 'np.array (list (range (x)))' use 'np.arange (x)', y para crear el índice, puede usar 'np.s _ [:: 2]' . – Michael

25

Hay una función numpy incorporada 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]) 
+2

Bueno saberlo. Estaba pensando que np.delete sería más lento pero, por desgracia, el tiempo para 1000 enteros dice que eliminar es x2 más rápido. – wbg

0

Si no se conoce el índice, no se puede utilizar logical_and

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