- 공유 링크 만들기
- 이메일
- 기타 앱
인덱스와 슬라이싱(index & slicing)
인덱스
numpy의 자료형인 배열(array)은 리스트들로 구성됩니다. 객체 a와 같이 한개의 리스트 작성된 경우를 벡터(vector)라고 합니다.
다음 코드의 랜덤수 생성은 랜덤수 생성을 위한 numpy 함수들 참조
np.random.seed(10) a=np.random.randint(0, 11, size=10) a
array([ 9, 4, 0, 1, 9, 0, 1, 10, 8, 9])
print(f"a의 차원,:{a.ndim}, a의 모양{a.shape}")
a의 차원,:1, a의 모양(10,)
위 결과와 같이 객체 a는 1차원으로 10개의 요소를 포함합니다. 벡터는 1차원이므로 1개의 축만이 존재하므로 객체의 모양은 "크기,"와 같이 숫자 한개로 표시됩니다.
리스트는 최왼쪽부터 0으로 시작되는 음이 아닌 정수인 인덱스를 가집니다(문자열의 인덱스 참조). 배열 역시 리스트로 구성되므로 같은 형태의 인덱스를 가집니다(표 1).
요소 | 9 | 4 | 0 | 1 | 9 | 0 | 1 | 10 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
인덱스 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
역인덱스 | -10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
표 1에서 나타낸 것과 같이 인덱스(index)는 최왼쪽의 요소부터 시작하는 음이 아닌 정수이며 역으로 마지막 요소를 -1로 시작하는 음의 정수를 인덱스로 사용할 수 있습니다. 이를 역인덱스(inverse index)라고 합니다.
표1의 형식으로 인덱스를 사용하여 지정한 위치의 값을 호출하거나 수정할 수 있습니다.
객체이름[인덱스] | (식 1) |
a[2]
0
a[2]=123; a
array([ 9, 4, 123, 1, 9, 0, 1, 10, 8, 9])
2차원인 행렬(matrix)의 경우는 두 개의 축을 가집니다. 다음 객체 A는 2개의 리스트로 구성된 행렬입니다.
np.random.seed(3) A=np.random.randint(0, 10, size=(2,5)) A
array([[8, 9, 3, 8, 8], [0, 5, 3, 9, 9]])
print(f"A의 차원,:{A.ndim}, A의 모양{A.shape}")
A의 차원,:2, A의 모양(2, 5)
위 객체 A는 2차원이므로 두 개의 축이 필요합니다. 이것은 이 객체의 모양이 두개의 숫자로 이루어진 것으로 알 수 있습니다. 표 2는 이 객체를 나타낸 것으로 가로방향을 행(row)축, 세로방향을 열(column)축으로 나타냅니다.
0 열 | 1 열 | 2 열 | 3 열 | 4 열 | |
---|---|---|---|---|---|
0 행 | 8 | 9 | 3 | 8 | 8 |
1 행 | 0 | 5 | 3 | 9 | 9 |
표 2와 같이 객체 A의 각 요소는 행과 열의 인덱스를 가집니다. 예를 들어 0행과 0열에 위치한 요소는 8이 됩니다. 즉, 8의 인덱스는 (0, 0)이 되며 첫번째 인덱스는 행, 두번째 인덱스는 열을 나타냅니다. 그러므로 행렬의 요소를 호출하거나 수정하기 위해서는 행과 열의 인덱스들을 모두 적용해야 합니다(식 2).
객체이름[행인덱스, 열인덱스] | (식 2) |
A[0,0]
8
A[1, 0]=100 A
array([[ 8, 9, 3, 8, 8], [100, 5, 3, 9, 9]])
다음 객체 B는 3차원으로 두 개의 행렬을 연결한 것입니다.객체.shape의 결과는 3개의 숫자로 반환됩니다.
np.random.seed(3) B=np.random.randint(0, 10, size=(2, 2,5)) B
array([[[8, 9, 3, 8, 8], [0, 5, 3, 9, 9]], [[5, 7, 6, 0, 4], [7, 8, 1, 6, 2]]])
print(f"B의 차원,:{B.ndim}, B의 모양{B.shape}")
B의 차원,:3, B의 모양(2, 2, 5)
위 결과와 같이 B는 3차원이며 모양은 3개의 수들로 구성되며 각 수 역시 인덱스가 부여됩니다. 이 인덱스를 축인덱스(axis index)라고 하며 numpy의 배열에 적용할 수 있는 많은 함수나 메서드의 인수 axis에 전달하는 값이 됩니다. 이 축인덱스는 다음과 같이 나타낼 수 있습니다.
축인덱스 | 3 | 2 | 1 |
---|---|---|---|
모양 | 2 | 2 | 5 |
그러므로 식 1과 식 2를 일반화하여 나타내면 식 3과 같습니다.
객체이름[n차원인덱스, …, 2차원(행)인덱스, 1차원(열)인덱스] | (식 3) |
B[1,0,1]
7
슬라이싱
식 3은 인덱스를 사용하여 한 개의 요소를 호출할 수 있지만 식 4와 같이 여러 인덱스들의 조합을 적용하여 하나 이상의 요소들을 호출하거나 수정할 수 있습니다. 물론 새로운 객체를 생성할 수 있습니다.
객체[인덱스1: 인덱스2:인덱스 간격] | (식 4) |
(인덱스1) ~ (인덱스2)-1 중에 지정한 간격에 대응하는 요소를 호출 간격의 기본값은 1이며 생략가능 인덱스1을 생략하면 0으로 인식 | |
위 구문은 각 축에 별도로 지정, 2차원인 경우 객체[행인덱스1: 행인덱스2, 열인덱스1: 열인덱스2] |
위 식 4는 1개 이상의 요소를 호출하는 경우로 슬라이싱(slicing)이라고 합니다. 물론 인덱스 1개일 경우는 대응하는 요소는 1개이며 그 호출된 결과의 자료형은 요소 자체의 리터럴자료형(숫자형 또는 문자형)이 됩니다. 반면에 두개 이상의 요소를 호출한 결과는 배열이 됩니다.
np.random.seed(3) A=np.random.randint(0, 10, size=(3,5)) A
array([[8, 9, 3, 8, 8], [0, 5, 3, 9, 9], [5, 7, 6, 0, 4]])
A[0,1], type(A[0,1])
(9, numpy.int32)
A[0:3,2]
array([3, 3, 6])
표 3은 행렬 객체에서의 슬라이싱 규칙을 나타내고 있습니다. 이 규칙은 차원 인덱스를 고려하면 모든차원의 배열에 적용됩니다.
규칙 | 내용 |
---|---|
A[r, c] | r 번째 행과 c 번째 열의 값 |
A[r1:rn:간격, c1:cn:간격] | 식 1.1.7을 행과 열 각각에 적용. 이 경우 행과 열의 인덱스 갯수는 같아야 함 |
A[::-1, ::-1] | 행과 열 모두 역순으로 정렬 |
A[ :, :] | 콜론(:)은 각 행과 열의 모든 범위를 의미 |
A[-1,-1] | 마지막행과 열의 요소. 인덱스에서 음(-) 값은 뒤 쪽을 나타냄. |
x=np.array([9, 2, 1, 3, 8, 3, 6, 7]) x
array([9, 2, 1, 3, 8, 3, 6, 7])
x[::-1]
array([7, 6, 3, 8, 3, 1, 2, 9])
x[::2]
array([9, 1, 8, 6])
np.random.seed(5) x=np.random.randint(10, size=(2,2)) x
array([[3, 6], [6, 0]])
x[::-1, :]
array([[6, 0], [3, 6]])
x[:,::-1]
array([[6, 3], [0, 6]])
x[::-1,::-1]
array([[0, 6], [6, 3]])
슬라이싱을 위해 정수와 콜론(:)을 사용하는 방법 외에 불리언 (boolean)으로 실행 할 수 있습니다.
np.random.seed(9) x=np.random.randint(30, size=(10)) x
array([28, 21, 22, 24, 27, 22, 29, 1, 22, 20])
연산자 %는 나머지를 반환합니다.
x%3==0
array([False, True, False, True, True, False, False, False, False, False])
다음 코드는 객체 x의 각 요소를 3으로 나누어지는 수만으로 구성
x[x%3==0]
array([21, 24, 27])
댓글
댓글 쓰기