numpy 배열에서 특정 요소를 제거하는 방법


212

numpy 배열에서 특정 요소를 어떻게 제거 할 수 있습니까? 내가 가지고 있다고

import numpy as np

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

그때 제거 할 3,4,7에서 a. 내가 아는 것은 값의 색인입니다 ( index=[2,3,6]).

답변:


285

numpy.delete () 사용 - 삭제 된 축을 따라 하위 배열이 있는 배열을 반환합니다.

numpy.delete(a, index)

특정 질문에 대해 :

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

배열 스칼라 는 파이썬의 문자열과 유사하게 변경할 수 없으므로 numpy.delete()새 배열 을 반환 하므로 변경 할 때마다 새 객체가 생성됩니다. 즉, 문서 를 인용하려면 :delete()

" obj로 지정된 요소가 제거 된 arr 사본 이 삭제 되었습니다. 삭제는 제자리에서 발생하지 않습니다 ."

내가 게시 한 코드에 출력이 있으면 코드를 실행 한 결과입니다.


1
@IngviGautsson 편집 할 때 요소의 올바른 값도 2, 3, 6에서 3, 4, 7로 변경했습니다. 이제 코드를 실행하면 원래 경우와 같이 올바른 출력을 얻지 못합니다. "편집 편집 중
Levon

1
AttributeError : 'list'객체에 'delete'속성이 없습니다
munmunbb

3
@IngviGautsson 아니오, 귀하의 의견은 잘못된 것입니다. 이것은 예상대로 작동합니다. 그러나 numpy.delete ()의 문서는 "종종 부울 마스크를 사용하는 것이 바람직하다"고 언급합니다. 그 예도 나와 있습니다.
Biggsy

1
@Levon 2D에 대한 예제를 추가 할 수 있습니까?
MattS

7
@IngviGautsson 당신이 틀 렸습니다. 항목 자체가 아니라 항목의 인덱스를 삭제해야합니다.
Le Frite

64

이를 돕기 위해 수많은 내장 함수가 있습니다.

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

7
알아 둘만 한. 나는 np.delete가 느리지 만 슬프다 고 생각했습니다 .1000 정수의 timeit은 delete가 x2 더 빠릅니다.
wbg

1
이것은 제거하려는 인덱스 / 지표를 제공하지 않고 배열의 에서 작동하기 때문에 훌륭 합니다. 예를 들면 :np.setdiff1d(np.array(['one','two']),np.array(['two', 'three']))
MD004

이것은 또한 출력을 정렬하는데, 이는 원하는 것이 아닐 수도 있습니다. 그렇지 않으면 아주 좋습니다.
rayzinnz

질문은 "내가 아는 것은 값의 색인이다"라고 말합니다. 따라서 값으로 제거하지 않고 인덱스로 항목을 제거하는 것입니다.
Sherzod

35

Numpy 배열은 변경할 수 없으므로 기술적으로 항목을 삭제할 수 없습니다. 그러나 원하지 않는 값없이 다음과 같이 배열을 구성 할 수 있습니다 .

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

1
'불변'에 대해 +1 numpy 배열은 크기의 빠른 변경 (요소 추가 / 삭제)에 적합하지 않다는 점을 기억하는 것이 좋습니다.
eumiro

38
기술적으로, numpy 배열은 변경 가능합니다. 예를 들면 다음과 같습니다. a[0]=1수정합니다 a. 그러나 크기를 조정할 수는 없습니다.
btel

3
정의는 불변이라고 말하지만 새로운 값을 할당하여 수정하면 불변은 어떻게됩니까?
JSR

16

값으로 삭제하려면 :

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

문제는 특정 값을 가진 항목을 제거하지 않고 인덱스로 항목을 제거하는 것입니다.
Sherzod

5

멍청한 사람이 아닌 나는 총을 맞았습니다.

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

내 테스트에 따르면 성능이 뛰어납니다 numpy.delete(). 초기 배열의 작은 크기로 인해 왜 그런지 모르겠습니다.

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

그것은 (예상했던 것과 반대 방향으로) 상당히 중요한 차이입니다.이 이유가 무엇인지 아는 사람 있습니까?

더 이상하게도, numpy.delete()목록을 전달 하면 목록을 반복하여 단일 인덱스를 제공하는 것보다 성능이 떨어집니다.

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

편집 : 배열의 크기와 관련이있는 것 같습니다. 큰 배열의 경우 numpy.delete()훨씬 빠릅니다.

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

분명히, 당신은 항상 명확성을 위해 가고 바퀴를 재발 명하지 않아야하기 때문에 이것은 모두 관련이 없습니다. 그러나 나는 조금 흥미 롭다는 것을 알았습니다.


2
실제로 비교하는 것에주의하십시오! 당신이 a = delte_stuff(a)만드는 첫 번째 반복에서 a매일 반복과 작은. inbuild 함수를 사용하면 값을 다시 a에 저장하지 않으므로 원래 크기를 유지합니다! 그 외에도, 항목 세트를 만들 index거나 항목을 삭제할지 여부를 확인 하여 기능을 크게 향상시킬 수 있습니다 . 두 가지를 모두 고치면 10k 항목을 얻습니다. 함께 루프 당 6.22 msec, 4.48 msec for으로 numpy.delete예상되는 것입니다.
Michael

2
힌트 두 개 더 : np.array(list(range(x)))use 대신 np.arange(x)인덱스를 만드는 데 사용할 수 있습니다 np.s_[::2].
Michael

1

색인을 모르면 사용할 수 없습니다 logical_and

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

1

np.delete제거하려는 요소의 인덱스를 알고 있다면 사용하는 것이 가장 빠른 방법입니다. 그러나 완전성을 위해의 도움으로 생성 된 부울 마스크를 사용하여 배열 요소를 "제거"하는 다른 방법을 추가하겠습니다 np.isin. 이 방법을 사용하면 요소를 직접 또는 색인으로 지정하여 요소를 제거 할 수 있습니다.

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

지수로 제거 :

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

요소별로 제거합니다 (원본 a은 이전 줄에서 다시 작성되었으므로 다시 작성해야 함).

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

0

특정 인덱스 제거 (매트릭스에서 16과 21을 제거했습니다)

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

산출:

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

0

세트를 사용할 수도 있습니다.

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]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.