1_5_ndarray_Indexing_and_Slicing2

NumPy Master Class

Chapter1 ndarray

Notebook5 ndarray Indexing and Slicing2

이번 notebook에서는 ndarray의 indexing, slicing의 중요한 특징에 대해서 알아본다.

먼저 핵심만 말하면 python list에서 indexing, slicing을 하면 복사본을 만들지만 다량의 data를 다루고, indexing과 slicing이 빈번히 일어나는 ndarray에서는 indexing, slicing을 하면 새로운 ndarray를 만드는 것이 아니라 기존 ndarray에 참조를 하므로 기존 ndarray에 영향을 미칠 수 있다.

먼저 python list의 indexing에 대해서 살펴보자.

In [7]:
import numpy as np
In [44]:
python_list = [[1,2],[3,4]]

print("original python_list:", python_list, '\n')
element1 = python_list[0] # 첫 번째 원소 추출
python_list[0] = [10,10] # 원래의 python list의 첫 번째 원소들을 10으로 바꿈

print("python_list:", python_list)
print("element1:", element1)
original python_list: [[1, 2], [3, 4]] 

python_list: [[10, 10], [3, 4]]
element1: [1, 2]

Python을 많이 다뤄본 사람이라면 위의 결과는 당연해 보인다. 먼저 첫 번째 element를 뽑아내면 새로운 memory에 element1가 할당되기 때문에 기존 python_list를 수정해도 element1에는 영향을 미치지 않는다.

하지만 ndarray는 다른 결과를 보여준다.

In [50]:
np_arr = np.array([[1,2],[3,4]])

print("original np_arr:", np_arr, '\n')
element1 = np_arr[0] # 첫 번째 원소 추출
np_arr[0] = [10, 10] # 원래의 ndarray의 첫 번째 원소들을 10으로 바꿈

print("nd_arr:\n", np_arr)
print("element1:", element1)
original np_arr: [[1 2]
 [3 4]] 

nd_arr:
 [[10 10]
 [ 3  4]]
element1: [10 10]

위에서 분명 element1를 수정한 적이 없는데도 마지막 줄에서 확인할 수 있듯이 np_arr를 수정하니 element1도 같이 수정되었다.

여기서 numpy의 철학을 엿볼 수 있다. ndarray는 큰 data를 다루고, indexing과 slicing이 빈번히 일어나므로 최대한 memory를 아끼려는 모습을 보여준다.

이 때문에 불필요하게 새로운 ndarray를 만들지 않고 참조를 이용하여 indexing, slicing을 한다.

이런 ndarray의 철학 덕분에 큰 data를 다룰 때 우리가 가진 RAM을 효율적으로 쓸 수 있지만, 기존 ndarray를 수정하면 indexing, slicing된 data에 영향을 미치므로 예기치 않은 결과를 얻을 수 있다는 단점이 있다.

따라서 저자는 보통 indexing, slicing을 할 때 copy()함수를 함께 이용한다.

In [51]:
np_arr = np.array([[1,2],[3,4]])

print("original np_arr:", np_arr, '\n')
element1 = np_arr[0].copy() # 첫 번째 원소 추출
np_arr[0] = [10, 10] # 원래의 ndarray의 첫 번째 원소들을 10으로 바꿈

print("nd_arr:\n", np_arr)
print("element1:", element1)
original np_arr: [[1 2]
 [3 4]] 

nd_arr:
 [[10 10]
 [ 3  4]]
element1: [1 2]

위에서 달라진 점은 딱 하나이다. indexing을 하면서 copy() 함수를 같이 사용했다. 이 copy()함수는 새로운 memory를 잡아 element1에 값을 할당한다.

따라서 기존 ndarray의 참조를 사용하지 않으므로 원래의 ndarray를 수정해도 element1에는 영향을 주지 않는다.

+ Recent posts