Hoe specifieke elementen in een numpy array te verwijderen

Hoe kan ik bepaalde specifieke elementen uit een numpy-array verwijderen? Zeg ik heb

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

Ik wil dan 3,4,7verwijderen uit a. Alles wat ik weet is de index van de waarden (index=[2,3,6]).


Antwoord 1, autoriteit 100%

Gebruik numpy.delete()– retourneert een nieuwearray met subarrays langs een as verwijderd

numpy.delete(a, index)

Voor uw specifieke vraag:

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

Merk op dat numpy.delete()een nieuwe array retourneert sinds array scalarszijn onveranderlijk, vergelijkbaar met strings in Python, dus elke keer dat er een wijziging in wordt aangebracht, wordt er een nieuw object gemaakt. Dat wil zeggen, om de delete()documenten:

“Een kopievan arr met de elementen gespecificeerd door obj verwijderd. Merk op dat
verwijderen gebeurt niet ter plaatse
…”

Als de code die ik post uitvoer heeft, is dit het resultaat van het uitvoeren van de code.


Antwoord 2, autoriteit 25%

Er is een numpy ingebouwde functie om daarbij te helpen.

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

Antwoord 3, autoriteit 12%

Een Numpy-array is onveranderlijk, wat betekent dat je er technisch gezien geen item uit kunt verwijderen. U kunt echter een nieuwearray maken zonder de waarden die u niet wilt, zoals deze:

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

Antwoord 4, autoriteit 9%

Wissen op waarde:

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

Antwoord 5, autoriteit 2%

Het gebruik van np.deleteis de snelste manier om dit te doen, als we de indexen kennen van de elementen die we willen verwijderen. Laat me echter voor de volledigheid een andere manier toevoegen om array-elementen te “verwijderen” met behulp van een booleaans masker dat is gemaakt met behulp van np.isin. Met deze methode kunnen we de elementen verwijderen door ze rechtstreeks of via hun indexen te specificeren:

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

Verwijderen op index:

indices_to_remove = [2, 3, 6]
a = a[~np.isin(np.arange(a.size), indices_to_remove)]

Verwijderen op elementen(vergeet niet de originele aopnieuw te maken aangezien deze in de vorige regel is herschreven):

elements_to_remove = a[indices_to_remove]  # [3, 4, 7]
a = a[~np.isin(a, elements_to_remove)]

Antwoord 6

Omdat ik geen dom persoon was, heb ik een poging gewaagd met:

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

Volgens mijn tests presteert dit beter dan numpy.delete(). Ik weet niet waarom dat het geval zou zijn, misschien vanwege de kleine omvang van de initiële array?

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

Dat is een behoorlijk significant verschil (in de tegenovergestelde richting van wat ik had verwacht), heeft iemand enig idee waarom dit het geval zou zijn?

Nog vreemder, het doorgeven van numpy.delete()aan een lijst presteert slechter dan door de lijst bladeren en er enkele indices aan geven.

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

Bewerken: het lijkt te maken te hebben met de grootte van de array. Met grote arrays is numpy.delete()aanzienlijk sneller.

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

Natuurlijk is dit allemaal vrij irrelevant, omdat je altijd voor duidelijkheid moet gaan en het wiel niet opnieuw moet uitvinden, maar ik vond het een beetje interessant, dus ik dacht ik laat het hier bij.


Antwoord 7

Als u de index niet kent, kunt u logical_and

niet gebruiken

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

Antwoord 8

het begrijpen van een lijst kan ook een interessante benadering zijn.

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]

Antwoord 9

Verwijder specifieke index (ik heb 16 en 21 uit matrix verwijderd)

import numpy as np
mat = np.arange(12,26)
a = [4,9]
del_map = np.delete(mat, a)
del_map.reshape(3,4)

Uitvoer:

array([[12, 13, 14, 15],
      [17, 18, 19, 20],
      [22, 23, 24, 25]])

Antwoord 10

Je kunt ook sets gebruiken:

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]

Antwoord 11

Als je de indexen van de elementen die je wilt verwijderen niet hebt, kun je de functie in1dgeleverd door numpy.

De functie retourneert Trueals het element van een 1-D array ook aanwezig is in een tweede array. Om de elementen te verwijderen, hoeft u alleen de waarden die door deze functie worden geretourneerd, te negeren.

Merk op dat deze methode de volgorde behoudtvan de originele array.

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

Other episodes