2022년 10월 12일 수요일

Numpy Slicing

 

슬라이싱을 사용하면 배열의 일부를 추출하여 새 배열을 생성할 수 있습니다. Python list를 사용하여 배열을 슬라이스 할 때 결과 배열은 copy이지만 NumPy에서 배열은 동일한 기본 버퍼의 참조입니다.

슬라이싱이 numpy와 python이 약간 차이가 있습니다. 기본 파이썬의 경우는 slice를 할 경우 copy를 합니다. 즉, copy된 부분을 고쳐도 원본이 변경되지 않습니다. 그러나 numpy slice는 참조로 배열을 가져옵니다. 그 얘기는 slice된것을 수정할 경우, 원본도 같이 수정이 됩니다.

a = [1,2,3,4,5] # python기본 리스트로 생성합니다. 
b = a[2:4] # deep copy

print(a) 
print(b)
# [1, 2, 3, 4, 5]
# [3, 4]

b[1] = 7
print(a)
print(b)

# [1, 2, 3, 4, 5]
# [3, 7]

아래는 numpy case입니다.

import numpy as np
A = np.arange(1,6)  # numpy method로 생성되어야합니다. 

B = A[2:4] # shallow copy 
print (A)
print (B)
# [1, 2, 3, 4, 5]
# [3, 4]

B[1] = 7
print (A)
print (B)
# [1, 2, 3, 7, 5]
# [3, 7]

또, numpy slice는 step을 지원합니다. 배열의 일부만 추출할 수 있습니다. 아래와 같이 a[1:5:2]와 같은식으로 지정하면, for문 비슷하게 1부터 5까지 step 2만큼씩해서 리스트를 생성합니다.

>>> a = np.arange(10, 16)
>>> a
array([10, 11, 12, 13, 14, 15])
>>> a[1:5]
array([11, 12, 13, 14])


>>> a[1:5:2]
array([11, 13])

이것에 대한 응용으로 아래와 같이도 사용할 수 있습니다.

>>> a[::2]
array([10, 12, 14])
>>> a[:5:2]
array([10, 12, 14])
>>> a[:5:]
array([10, 11, 12, 13, 14])

다음은 2차원 array관련입니다. 아래 구문은 0번 row만 취합니다.

>>> A = np.arange(10, 19).reshape((3, 3))
>>> A
array([[10, 11, 12],
 [13, 14, 15],
 [16, 17, 18]])
>>> A[0,:]
array([10, 11, 12])

아래와 같이 하면 첫번째 column만 취합니다.

>>> A[:,0]
array([10, 13, 16])

아래와 같이 할 경우 (3,3) matrix에서 (2,2) matrix를 취합니다.

>>> A[0:2, 0:2]
array([[10, 11],
 [13, 14]])

아래는 row를 0행, 2행만 선택적으로 취합니다. column은 0:2로 취하고요

>>> A[[0,2], 0:2]
array([[10, 11],
 [16, 17]])

위 방법들은 다 이해하기도 어렵고 이런 류의 식들은 사실 머리로 이해하기보다는, 자주 쓰면서 손에 익는 류라고 보면 될 거 같습니다. 이 NumPy가 비슷하면서도 기존 파이썬과의 차이점들이 존재하니 이런 부분들을 이해하고 차이를 구분해서 쓰는게 중요해 보이네요

댓글 없음:

댓글 쓰기