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.