파이썬 numpy array 인덱싱과 슬라이싱
파이썬 넘파이 어레이(배열)의 인덱싱, 슬라이싱 과정에 대해서 살펴보고,
몇 가지 중요한 특징과 예제를 정리해보는 시간을 가져보겠습니다.
아래의 간단한 2차원 array를 대상으로 예제를 설명하겠습니다.
import numpy as np
a = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]])
넘파이 어레이 인덱싱
인덱싱은 원소 1개만을 골라 추출하는 과정을 일컫습니다.
0번부터 인덱스가 시작함에 주의하며, axis마다 원하는 원소의
좌표를 순서대로 지정해주시면 됩니다.
뒤 쪽부터 인덱스를 가져오는 -1, -2, ...의 인덱싱도 리스트처럼 지원합니다.
예를 들어, 두 번째 행, 4번째 열의 값을 가져오는 경우,
a[1, 3] 혹은 a[1][3] 처럼 값을 가져올 수 있습니다.
두 경우 모두 8의 값을 가져오게 됩니다.
a[1, 3] # 8
a[1][3] # 8
그러나, 실제 사용에서는 a[1, 3]과 같은 인덱싱 방법이 권장됩니다.
수행 시간의 이점이 있는데, 간단한 실험을 해보도록 하겠습니다.
import time
start = time.time()
for i in range(10 ** 7):
a[1, 3]
print(time.time() - start) # 약 2.2초
start = time.time()
for i in range(10 ** 7):
a[1][3]
print(time.time() - start) # 약 4.4초
a[1][3] 방식의 접근법은 사실상 인덱싱을 2번하는 과정과 동일하기에,
약 2배의 시간이 소요된 것을 확인할 수 있었습니다.
넘파이 어레이 전체 슬라이싱
슬라이싱은 여러개의 원소를 동시에 가져오는 과정을 일컫습니다.
가장 간단한 경우로 특정 axis(행, 열)의 원소 전체를 추출하는 예제를 보겠습니다.
1개의 행 혹은 1개의 열을 통째로 가져오는 예시입니다.
특정 axis 전체를 가져오는 것은 : 혹은 ... 으로 표현이 가능합니다.
a[2] # array([ 9, 10, 11, 12])
a[2, :] # array([ 9, 10, 11, 12])
a[:, 1] # array([ 2, 6, 10, 14])
a[..., 1] # array([ 2, 6, 10, 14])
가장 첫 axis(행)을 대상으로 가져올 때는, a[2] 처럼만 지정해도 무관합니다.
그림으로 위 과정을 요약하면 다음과 같습니다.
어레이 인덱싱과 슬라이싱의 차이 : 배열의 차원
인덱싱과 슬라이싱으로 같은 위치를 가져오는 작업을 수행해도 결과는 다를 수 있습니다.
인덱싱과 슬라이싱의 차이는 인덱싱은 차원을 자동으로 낮춰서 변환한 결과를 반환하는데,
반면 슬라이싱은 차원을 유지하면서 결과를 반환하게 됩니다.
예를 들어, 2차원 array에서 1개의 축에 인덱싱을 적용하면 결과는 1차원으로 반환되지만,
두 축 모두 슬라이싱을 적용하면 2차원으로 결과가 반환됩니다.
a[2, 1:3] # array([10, 11]) : 1차원
a[2:3, 1:3] # array([[10, 11]]) : 2차원
a[..., -1]
# array([ 4, 8, 12, 16])
a[..., -1:]
'''array([[ 4],
[ 8],
[12],
[16]])'''
a[2, 1:3]과 a[2:3, 1:3]이 가져오는 위치는 동일하나, 반환되는 차원이 다릅니다.
a[..., -1:]도 2차원의 모양을 가지는 열벡터 모양으로 결과가 반환되었습니다.
numpy array 슬라이싱
1:3 처럼 1~2번 위치를 슬라이싱하거나, :3처럼 처음 ~ 2번 위치,
1: 처럼 1번 위치~끝 부분을 슬라이싱하는 원리는 리스트와 동일합니다.
각 axis마다 슬라이싱 결과가 반영되는데, 그림으로 이해하면 다음과 같습니다.
실제 코드로 실행한 결과는 다음과 같습니다.
a[2, 1:3] # array([10, 11])
a[:2, 1:3]
'''
array([[2, 3],
[6, 7]])'''
::2 처럼 2칸씩 건너 뛰면서 슬라이싱 하거나,
1::2 처럼 1번 위치부터 2칸씩 건너 뛰는 방식,
::-1 으로 역순으로 슬라이싱하는 방식 등도 리스트와 마찬가지로 적용 가능합니다.
마찬가지로 각 axis마다 해당하는 위치들의 원소를 모아서 반환합니다.
실행 코드의 결과를 살펴보면서 포스팅 마무리를 하겠습니다.
a[::2, 1] # array([ 2, 10])
a[::2, 1::2]
'''array([[ 2, 4],
[10, 12]])'''
a[::2, ...]
'''array([[ 1, 2, 3, 4],
[ 9, 10, 11, 12]])'''
a[::2, ::-1]
'''array([[ 4, 3, 2, 1],
[12, 11, 10, 9]])'''
'Python > Numpy' 카테고리의 다른 글
[Numpy] 배열을 반복하여 쌓는 함수 np.tile 사용법(그림으로 정리) (0) | 2022.01.13 |
---|---|
[Numpy] 파이썬 리스트를 어레이로, 어레이를 리스트로 변환(tolist 함수) (0) | 2022.01.09 |
[Numpy] 파이썬 리스트 vs 넘파이 어레이(배열) 차이 (0) | 2022.01.09 |