Como posso remover alguns elementos específicos de uma matriz numpy? Diga que eu tenho
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
Eu quero remover 3,4,7
de a
. Tudo o que sei é o índice dos valores ( index=[2,3,6]
).
Como posso remover alguns elementos específicos de uma matriz numpy? Diga que eu tenho
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9])
Eu quero remover 3,4,7
de a
. Tudo o que sei é o índice dos valores ( index=[2,3,6]
).
Respostas:
Use numpy.delete () - retorna uma nova matriz com sub-matrizes ao longo de um eixo excluído
numpy.delete(a, index)
Para sua pergunta 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]`
Observe que numpy.delete()
retorna uma nova matriz, pois os escalares da matriz são imutáveis, semelhantes às seqüências de caracteres no Python, portanto, toda vez que uma alteração é feita, um novo objeto é criado. Ou seja, para citar os delete()
documentos :
"Uma cópia de arr com os elementos especificados por obj removidos. Observe que a exclusão não ocorre no local ..."
Se o código que eu postar tiver saída, é o resultado da execução do código.
Há uma função embutida numpy para ajudar nisso.
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']))
Uma matriz Numpy é imutável , o que significa que você tecnicamente não pode excluir um item dela. No entanto, você pode construir uma nova matriz sem os valores que não deseja, assim:
b = np.delete(a, [2,3,6])
a[0]=1
modifica a
no local. Mas eles não podem ser redimensionados.
Para excluir por valor:
modified_array = np.delete(original_array, np.where(original_array == value_to_delete))
Não sendo uma pessoa entorpecida, tirei uma foto com:
>>> 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])
De acordo com meus testes, isso supera numpy.delete()
. Não sei por que esse seria o caso, talvez devido ao pequeno tamanho da 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
Essa é uma diferença bastante significativa (na direção oposta ao que eu estava esperando), alguém tem alguma idéia de por que esse seria o caso?
Ainda mais estranhamente, passar numpy.delete()
uma lista tem um desempenho pior do que percorrer a lista e fornecer í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 ter a ver com o tamanho da matriz. Com matrizes grandes, numpy.delete()
é significativamente mais 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, tudo isso é irrelevante, pois você sempre deve ter clareza e evitar reinventar a roda, mas achei um pouco interessante, então pensei em deixá-la aqui.
a = delte_stuff(a)
em sua primeira iteração, que a
diminui a cada iteração. Quando você usa a função inbuild, não armazena o valor novamente em a, o que mantém a no tamanho original! Além disso, você pode acelerar drasticamente sua função, ao criar um conjunto de index
e de verificar se é para excluir ou não um item. Corrigindo as duas coisas, recebo 10k itens: 6,22 ms por loop com sua função, 4,48 ms por numpy.delete
, o que é aproximadamente o que você esperaria.
np.array(list(range(x)))
usar np.arange(x)
e para criar o índice, você pode usar np.s_[::2]
.
Usar np.delete
é a maneira mais rápida de fazer isso, se soubermos os índices dos elementos que queremos remover. No entanto, para completar, deixe-me adicionar outra maneira de "remover" os elementos da matriz usando uma máscara booleana criada com a ajuda de np.isin
. Este método permite remover os elementos, especificando-os diretamente ou por seus índices:
import numpy as np
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
Remover por índices :
indices_to_remove = [2, 3, 6]
a = a[~np.isin(np.arange(a.size), indices_to_remove)]
Remova por elementos (não se esqueça de recriar o original, a
pois ele foi reescrito na linha anterior):
elements_to_remove = a[indices_to_remove] # [3, 4, 7]
a = a[~np.isin(a, elements_to_remove)]
Remover índice específico (eu removi 16 e 21 da matriz)
import numpy as np
mat = np.arange(12,26)
a = [4,9]
del_map = np.delete(mat, a)
del_map.reshape(3,4)
Resultado:
array([[12, 13, 14, 15],
[17, 18, 19, 20],
[22, 23, 24, 25]])