2012-06-12 24 views

Odpowiedz

160

Zastosowanie numpy.delete() - zwraca nowy tablicę z sub-macierzy wzdłuż osi usunięte

numpy.delete(a, index) 

dla konkretnego pytania:

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

Zauważ, że numpy.delete() zwraca nową tablicę od array scalars są niezmienny, podobny do łańcuchów w Pythonie, więc za każdym razem, gdy jest do niego wprowadzana zmiana, tworzony jest nowy obiekt. Tj zacytować delete()docs:

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

Jeśli kod zamieścić ma wyjścia, jest wynikiem działania kodu.

+1

Dziękuję bardzo. Próbowałem, żeby bur nie mógł z jakiegoś powodu zadziałać. To działa teraz –

+0

@DanielThaagaardAndreasen Szczęśliwy, że mogłem pomóc. – Levon

+1

Ta odpowiedź jest myląca. Drugim argumentem dla numpy.delete nie jest indeks elementu, który chcesz usunąć, ale rzeczywisty element, który chcesz usunąć. –

29

Tablica Numpy to immutable, co oznacza, że ​​technicznie nie można usunąć z niej elementu. Jednakże, można skonstruować nowy tablicę bez wartości, których nie chcesz, tak:

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

Dziękuję za odpowiedź: –

+0

+1 za wzmiankę o "niezmiennym" Dobrze jest pamiętać, że drobne tablice nie nadają się do szybkiego zmiany rozmiaru (dodawanie/usuwanie elementów) – eumiro

+20

technicznie, numpy tablice MOGĄ być zmienne, na przykład: 'a [0] = 1' modyfikuje' a' na miejscu, ale nie można zmienić ich rozmiaru – btel

4

Nie będąc numpy osoba, wziąłem strzał z:

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

Według moje testy, to lepsze wyniki niż numpy.delete(). Nie wiem, dlaczego tak się stało, może ze względu na mały rozmiar początkowej tablicy?

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 

To dość istotną różnicę (w kierunku przeciwnym do czego się spodziewałem), ktoś ma jakiś pomysł, dlaczego tak się stanie?

Jeszcze dziwniej, przekazując numpy.delete() listę wykonuje gorzej niż zapętlenie na liście i podanie jej pojedynczych indeksów.

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 

Edytuj: Wygląda na to, że ma do czynienia z rozmiarem tablicy. Przy dużych tablicach, numpy.delete() jest znacznie szybszy.

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 

Oczywiście, to wszystko jest bardzo istotne, ponieważ zawsze należy przejść dla jasności i uniknąć wyważania otwartych drzwi, ale okazało się to mało interesujący, więc pomyślałem, że go tu zostawić.

+2

Bądź ostrożny z tym, co faktycznie porównać! Masz "a = delte_stuff (a)" w swojej pierwszej iteracji, co powoduje, że 'a' jest mniejszy w każdej iteracji.Kiedy używasz funkcji inbuild, nie przechowujesz wartości z powrotem do a, która utrzymuje oryginalny rozmiar! To znaczy, że możesz drastycznie przyspieszyć swoją funkcję, gdy utworzysz zestaw ouf "indeksu" i sprawdź, czy usunąć element. Naprawię obie rzeczy, dostaję za 10k przedmiotów: 6.22 msec na pętlę z twoją funkcją, 4,48 ms dla 'numpy.delete', co jest mniej więcej tym, czego oczekiwałbyś. – Michael

+2

Dwie dodatkowe wskazówki: Zamiast 'np.array (list (range (x))) użyj' np.arange (x) ', a do stworzenia indeksu możesz użyć' np.s _ [:: 2] ' . – Michael

25

Istnieje wbudowana funkcja numpy.

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

Dobrze wiedzieć. Myślałem, że np.delete będzie wolniejszy, ale niestety, timeit dla 1000 liczb całkowitych mówi, że delete jest x2 szybsze. – wbg

0

Jeśli nie znasz indeksu, nie można używać logical_and

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