※ 일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있을 수 있으며 틀린 내용이 있으면 지적해주시면 감사하겠습니다.
numpy.nonzero 함수는 0이 아닌 요소의 인덱스를 얻을 수 있는 심플한 함수이다. 이번 포스트에서는 numpy.nonzero의 사용법에 대해서 해설하고자한다.
numpy.nonzero
numpy.nonzero 와 numpy.ndarray.nonzero의 두 가지 타입이 있으며, 사용방법은 거의 동일하다.
numpy.nonzero의 기본 문법은 다음과 같다.
numpy.nonzero(a)
파라미터명 | 데이터형 | 개요 |
a | array_like 배열에 해당하는 것 | 인덱스를 추출하고 싶은 배열을 지정한다. |
이 함수를 통해 반환되는 것은 각 축마다 0아 이닌 요소의 인덱스를 1차원 배열이다.
다음으로 numpy.ndarray.nonzero는 다음과 같다.
numpy.ndarray.nonzero()
이 numpy.ndarray.nonzero를 통해서는 각 축마다 0이 아닌 요소의 인덱스를 1차원 배열을 얻을 수 있으며, 배열(ndarray)의 튜플(tuple)의 형태이다.
참고로, 0 이외의 값을 가진 요소의 인덱스를 추출하고 싶은 경우는 x[x.astype(bool)] 혹은 x[x=!0] 사용하면 된다. 그리고 뒤에서 설명하겠지만 nonzero()로 얻어지는 인덱스는 차원축 마다 잘려 있다. 만약 요소마다의 인덱스를 획득하고 싶은 경우는 argwhere()를 사용하자.
샘플 코드
In [1]: import numpy as np
In [2]: a = np.random.randint(0, 10, size=20)
In [3]: a # 1차원 랜덤 배열
Out[3]: array([0, 7, 5, 8, 4, 9, 0, 2, 1, 7, 9, 0, 6, 9, 2, 6, 0, 8, 3, 9])
In [4]: np.nonzero(a) # 0이 아닌 요소의 인덱스를 획득
Out[4]: (array([ 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19]),)
In [5]: a.nonzero() # 이 형태로도 사용할 수 있다.
Out[5]: (array([ 1, 2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19]),)
In [6]: a[np.nonzero(a)] # 이 작성법으로 0이 아닌 요소로만 구성된 배열을 생성할 수 있다.
Out[6]: array([7, 5, 8, 4, 9, 2, 1, 7, 9, 6, 9, 2, 6, 8, 3, 9])
In [10]: b = np.random.randint(0, 10, size= (4,5)) # 4×5의 2차원 랜덤 배열
In [11]: b
Out[11]:
array([[4, 2, 1, 7, 8],
[5, 5, 0, 4, 7],
[7, 6, 9, 2, 9],
[0, 1, 2, 2, 6]])
In [12]: np.nonzero(b) # 첫 번째 배열은 "행" 방향의 인덱스, 두 번째 배열은 "열" 방향의 인덱스이다.
Out[12]:
(array([0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3]),
array([0, 1, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 3, 4, 1, 2, 3, 4]))
In [13]: b.nonzero()
Out[13]:
(array([0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3]),
array([0, 1, 2, 3, 4, 0, 1, 3, 4, 0, 1, 2, 3, 4, 1, 2, 3, 4]))
In [14]: b[b.nonzero()] # 0이 아닌 요소만을 추출했다.
Out[14]: array([4, 2, 1, 7, 8, 5, 5, 4, 7, 7, 6, 9, 2, 9, 1, 2, 2, 6])
numpy.where, numpy.argwhere과의 비교
0이 아닌 요소를 추출할 수 있는 또 다른 방법은 두 가지 더 있다. 하나가 numpy.where이고 다른 하나가 numpy.argwhere이다.
numpy.where에서는 3항 연산자도 사용할 수 있다. 예를 들면 다음과 같이 쓸 수 있다.
In [2]: a = np.random.randint(0, 10, size=(100, 100))
In [3]: b = np.ones(shape=(100, 100))
In [4]: np.where(a != 0, a, b)
Out[4]:
array([[ 5., 3., 2., ..., 9., 9., 8.],
[ 5., 7., 1., ..., 1., 7., 5.],
[ 7., 1., 9., ..., 6., 5., 4.],
...,
[ 2., 6., 3., ..., 9., 6., 9.],
[ 4., 2., 4., ..., 7., 3., 1.],
[ 9., 4., 7., ..., 3., 6., 5.]])
위에서 설명했듯 요소마다의 인덱스를 획득하고 싶은 경우는 argwhere()를 사용해서 구하면 된다. 참고로 np.argwhere(a)는 np.transpose(np.nonzero(a))와 동일하다.
In [1]: import numpy as np
In [2]: a = np.random.randint(0, 10, size=(100, 100))
In [3]: np.nonzero(a)
Out[3]: (array([ 0, 0, 0, ..., 99, 99, 99]), array([ 0, 1, 2, ..., 97, 98, 99]))
In [4]: np.where(a != 0)
Out[4]: (array([ 0, 0, 0, ..., 99, 99, 99]), array([ 0, 1, 2, ..., 97, 98, 99]))
In [5]: np.argwhere(a != 0)
Out[5]:
array([[ 0, 0],
[ 0, 1],
[ 0, 2],
...,
[99, 97],
[99, 98],
[99, 99]])
In [6]: np.transpose(np.nonzero(a))
Out[6]:
array([[ 0, 0],
[ 0, 1],
[ 0, 2],
...,
[99, 97],
[99, 98],
[99, 99]])
참고자료
'IT > 언어' 카테고리의 다른 글
[SQLAlchemy/Python] python바탕의 Query로 데이터 베이스 조작 (CRUD) (0) | 2022.11.10 |
---|---|
[python] 사전형의 리스트(list내의 dict)에서 키, 값 검색하기;get 메소드, filter 함수, 내포 표기 (0) | 2022.09.05 |
[python/openCV] openCV로 도형그리기 (0) | 2022.08.10 |
[python/openCV] 가로세로 비율을 유지한 채로 이미지를 리사이즈하기(이미지 사이즈 변경) (0) | 2022.08.08 |
[python/scipy] scipy.interpolate.interp2d를 이용한 2차원 데이터 보간 (0) | 2022.08.04 |