4.4.5 2차원 배열의 색인
[비유로 이해하기: 아파트 호수 찾기]
엑셀 시트나 행렬에서 특정 값을 가져오려면 행(Row)과 열(Column)의 좌표가 정확히 필요합니다. [행, 열] 좌표를 지정하여 원소 값을 콕 집어 가져올 수 있습니다. -1 인덱스를 활용하면 “맨 마지막(펜트하우스)”부터 역순으로 탐색할 수 있어 직관적입니다. 또한 리스트로 원하는 인덱스를 이빨 빠진 듯 불연속적으로 선택하는 방식을 ‘팬시 인덱싱(Fancy Indexing)’이라고 부르며, 추천 시스템처럼 유저가 좋아하는 상품 번호만 쏙쏙 골라 담을 때 막강한 힘을 발휘합니다.
다음 모양 (7, 8)의 2차원 배열 x가 있다.
from numpy import arange
x = arange(56).reshape(7, 8)
x
출력:
array([[ 0, 1, 2, 3, 4, 5, 6, 7],
[ 8, 9, 10, 11, 12, 13, 14, 15],
[16, 17, 18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29, 30, 31],
[32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47],
[48, 49, 50, 51, 52, 53, 54, 55]])
이미 배운 첨자 색인이나 슬라이싱은 고급 인덱싱과 다르다. 다음은 일반 색인 방법이다.
x[0, 1]
출력:
1
다음은 일반 슬라이싱 방법이다. 다음으로 모든 행(:)의 첨자 2열부터 7열(2:8)로 구성된 모양 (7, 6)의 2차원 배열이 반환된다.
x[:, 2:8]
출력:
array([[ 2, 3, 4, 5, 6, 7],
[10, 11, 12, 13, 14, 15],
[18, 19, 20, 21, 22, 23],
[26, 27, 28, 29, 30, 31],
[34, 35, 36, 37, 38, 39],
[42, 43, 44, 45, 46, 47],
[50, 51, 52, 53, 54, 55]])
다음은 간단한 고급 색인 방법으로 0축과 1축에 각각 목록이 기술된다. 결과는 첨자에 해당하는 값이다.
x[[0], [1]]
출력:
array([1])
다음으로 모든 행의 5열과 4열로 구성된 모양 (7, 2)의 2차원 배열이 반환된다.
x[:, [5, 4]]
출력:
array([[ 5, 4],
[13, 12],
[21, 20],
[29, 28],
[37, 36],
[45, 44],
[53, 52]])
다음으로 1행과 3행의 모든 열로 구성된 모양 (2, 8)의 2차원 배열이 반환된다.
x[[1, 3]]
출력:
array([[ 8, 9, 10, 11, 12, 13, 14, 15],
[24, 25, 26, 27, 28, 29, 30, 31]])
다음은 위 구문과 같으며 1행과 3행의 모든 열로 구성된 모양 (2, 8)의 2차원 배열이 반환된다.
x[[1, 3], :]
출력:
array([[ 8, 9, 10, 11, 12, 13, 14, 15],
[24, 25, 26, 27, 28, 29, 30, 31]])
다음처럼 0축과 1축의 배열의 수가 같으면 각각 대응되는 순서대로 첨자 [1, 2]와 [3, 2]에 해당하는 10과 26으로 구성된 모양 (2, )의 1차원 배열이 반환된다.
x[[1, 3], [2, 2]]
출력:
array([10, 26])
다음처럼 0축과 1축의 배열의 수가 같지 않으면, [2]가 브로드캐스팅이 수행되어 [2, 2]가 되어 각각 대응되는 순서대로 첨자 [1, 2]와 [3, 2]에 해당하는 10과 26으로 구성된 모양 (2, )의 1차원 배열이 반환된다. 결국, 위와 같다.
x[[1, 3], [2]]
출력:
array([10, 26])
다음도 0축과 1축의 배열의 수가 같으므로 각각 대응되는 순서대로 첨자 [1, 3]과 [3, 3]에 해당하는 11과 27로 구성된 모양 (2, )의 1차원 배열이 반환된다.
x[[1, 3], [3, 3]]
출력:
array([11, 27])
다음 코드는 [3]이 브로드캐스팅이 수행되어 [3, 3]이 되어 각각 대응되는 순서대로 첨자 [1, 3]과 [3, 3]에 해당하는 11(=x[1, 3])과 27(=x[3, 3])로 구성된 모양 (2, )의 1차원 배열이 반환된다. 결국, 위와 같다.
x[[1, 3], [3]]
출력:
array([11, 27])
다음처럼 브로드캐스팅이 될 수 없는 형태인 모양 (3, )과 모양 (2, )이면 오류가 발생한다.
from numpy import array
x[array([0, 2, 4]), array([0, 1])]
오류:
IndexError: shape mismatch: indexing arrays could not be broadcast together with shapes (3,) (2,)
다음 코드는 이미 알아보았듯이 1축의 1이 브로드캐스팅이 수행되어 [1, 1, 1]이 되어 각각 대응되는 순서대로 첨자 [0, 1]과 [2, 1], [4, 1]에 해당하는 [1, 17, 33]으로 구성된 모양 (3, )의 1차원 배열이 반환된다.
x[np.array([0, 2, 4]), 1]
출력:
array([ 1, 17, 33])
결과는 x[0, 1], x[2, 1], x[4, 1]의 참조 값으로 구성된 1차원 배열이 된다.
print(x[0, 1])
print(x[2, 1])
print(x[4, 1])
출력:
1
17
33