넘파이 배열(ndarray) 의 팬시 색인은 정수 리스트(혹은 배열)를 이용하여 여러 개를 동시에 선택하는 방식이다. 인덱싱은 항상 0으로 시작한다는 것에 유의하자. MATLAB/SCILAB/OCTAVE 에 익숙한 사용자는 인덱스가 0에서 시작된다는 것에 주의해야 한다. 이후 예제에서는 넘파이가 다음과 같이 임포트되었다고 가정한다.
>>> import numpy as np |
예를 들어서 다음과 같은 a 행렬을 고려하자.
>>> a=np.arange(24).reshape((6,4))>>> aarray([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11],[12, 13, 14, 15],[16, 17, 18, 19],[20, 21, 22, 23]]) |
여기서 특정한 행들을 선택하고 싶다면 원하는 순서대로 행번호를 적은 리스트나 배열로 인덱싱하면 된다.
>>> a[[3,0,5]]array([[12, 13, 14, 15],[ 0, 1, 2, 3],[20, 21, 22, 23]])>>> a[[-1,-3,2]]array([[20, 21, 22, 23],[12, 13, 14, 15],[ 8, 9, 10, 11]]) |
한 가지 주의할 점은 슬라이싱과 다르게 이런 식으로 반환되는 배열은 복사된 것이라는 점이다. 즉, 원본과 연결되지 않은 복사 객체가 반환된다. 따라서 원본의 갱신과 무관하게 된다.
또 한 가지 유의할 점이 있는데 다음과 같이 다중으로 인덱싱을 할 경우이다.
>>> a[:,[2,3]] #(1)array([[ 2, 3],[ 6, 7],[10, 11],[14, 15],[18, 19],[22, 23]])>>> a[[0,1],[2,3]] # (2)array([2, 7]) |
여기서 (1)에서와 같이 한 쪽이 모든 요소를 나타내는 콜론(:) 이 쓰인 경우는 해석이 쉽다. 즉, a 배열의 0번 열과 1번 열을 골라내는 것이다. 그런데 (2)의 경우는 MATLAB에 익숙하던 사용자라면 좀 의아할 것이다. 다음 표와 같이 0행, 1행과 2열, 3열이 겹치는 부분인 2x2 행렬이 반환된다고 오해하기 쉽기 때문이다.
2열
|
3열
| |||
0행
|
0
|
1
|
2
|
3
|
1행
|
4
|
5
|
6
|
7
|
8
|
9
|
10
|
11
| |
12
|
13
|
14
|
15
| |
16
|
17
|
18
|
19
| |
20
|
21
|
22
|
23
|
실제 동작은 (0,2) 요소와 (1,3)요소 두 개를 반환한다.
MATLAB과 같이 그리드 점에 있는 요소들의 집합인 2x2 행렬을 반환하게 하려면 np.ix_() 함수에 팬시 색인을 넘겨주어야 한다.
>>> a[np.ix_([0,1],[2,3])]array([[2, 3],[6, 7]]) |
이것은 사실 a[ [0,1] ][ :, [2,3] ] 과 같은 동작을 취한다.
그리고 a[1,2] 와 a[1][2] 는 같은 요소를 가리킨다.
>>> a[1,2]6>> a[1][2]6 |
하지만 이것으로 두 인덱싱이 같은 표현법이라고 오해하면 안 된다. 사실은 전혀 다르기 때문이다. 예를 들면 다음과 같다.
>>> a[:,2] # 2번 열만 뽑아낸다.array([ 2, 6, 10, 14, 18, 22])>>> a[:][2] # 이것은 a[2]와 같다.Out[41]: array([ 8, 9, 10, 11])>>> a[ [-1,-2], 1 ]array([21, 17])>>> a[[-1,-2]][1]array([16, 17, 18, 19]) |
마지막 예에서 a[[-1,-2]][1] 은 a[[-1,-2]] 행렬의 1번째 행을 뽑아내는 것이다. a[[-1,-2], 1] 과는 완전히 다르다.
댓글 없음:
댓글 쓰기