넘파이 어레이와 관련된 인덱싱과 슬라이싱 기능을 좀 더 알아본다.
In [1]:
import numpy as np
In [2]:
a = np.arange(0, 100, 10)
a
Out[2]:
이제 다른 정수들의 어레이를 이용한다.
이때 사용되는 정수들은 인덱싱 대상으로 삼는 어레이의 인덱스 값들로 이루어져야 한다.
그렇지 않으면 IndexError
가 발생한다.
정수들의 어레이를 이용하여 인덱싱을 하면 각 항목들에 대해 인덱싱을 실행한다. 동일한 인덱스가 반복되면 인덱싱도 반복된다. 따라서 리턴값의 모양은 인덱싱으로 사용된 어레이의 모양과 동일하다.
In [3]:
b = np.array([2, 3, 2, 4, 2])
In [4]:
a[b]
Out[4]:
인덱싱을 위해 어레이 대신에 리스트를 이용해도 동일한 결과를 얻는다.
In [5]:
c = [2, 3, 2, 4, 2]
In [6]:
a[c]
Out[6]:
마스크의 경우와 마찬가지로 정수들의 어레이를 이용하여 특정 위치의 값들을 변경할 수 있다.
In [7]:
a[[9, 7]] = -100
a
Out[7]:
In [8]:
a = np.arange(10)
In [9]:
idx = np.array([[3, 4], [9, 7]])
idx
Out[9]:
In [10]:
a[idx]
Out[10]:
아래 그림을 보면서 팬시 인덱싱을 연습해보자.
|
In [11]:
a = np.arange(6) + np.arange(0, 51, 10)[:, np.newaxis]
a
Out[11]:
In [12]:
a[(0, 1, 2, 3, 4), (1, 2, 3, 4, 5)]
Out[12]:
In [13]:
a[3:, [0, 2, 5]]
Out[13]:
In [14]:
a[(0, 2, 5), (2, 2, 2)]
Out[14]:
(2, 2, 2)
부분을 단순히 2
라고 적어도 된다.
이유는 브로드캐스팅이 자동 적용되어 (0, 2, 5)
의 모양과 통일시켜 주기 때문이다.
In [15]:
a[(0, 2, 5), 2]
Out[15]:
하지만 마스크 인덱싱을 활용할 수도 있다.
(0, 2, 5)
에 대응하는 마스크는 다음과 같다.
In [16]:
mask = np.array([1,0, 1, 0, 0, 1], dtype =bool)
따라서 아래와 같이 실행하면 동일한 결과를 얻는다.
In [17]:
a[mask, 2]
Out[17]:
In [18]:
a = [1, 2, 3]
In [19]:
b = a[0:2]
b
Out[19]:
b
의 값을 변경해도 a
는 영향을 받지 않는다.
In [20]:
b[0] = 4
b
Out[20]:
In [21]:
a
Out[21]:
In [22]:
c = np.array([1, 2, 3])
In [23]:
d = c[0:2]
d
Out[23]:
d
의 값을 변경하면 c
의 값도 변경된다.
In [24]:
d[0] = 4
d
Out[24]:
In [25]:
c
Out[25]:
어레이를 슬라이싱 하면 어레이를 새로 생성하는 것이 아니라 기존의 어레이를 관찰하며 필요한 정보만 보여준다. 즉, 슬라이싱을 위해 메모리를 새롭게 사용하지 않는다. 복사보다 뷰 방식을 사용하는 이유는 처리속도 및 메모리 활용성을 높이기 위해서이다.
뷰 방식을 사용하지 않으려면 copy
메소드를 사용하여 복사해야 한다.
In [26]:
e = np.arange(10)
g = e[::2].copy()
g
Out[26]:
In [27]:
g[0] = 12
g
Out[27]:
복사를 사용하였기 때문에 e
는 변하지 않는다.
In [28]:
e
Out[28]: