[Python.NumPy] ndarray indexing과 slicing
2020. 11. 30. 20:57ㆍPython과 머신러닝/NumPy 데이터 분석
0. 요약
- ndarray를 쓰면 기존 Java나 C와는 다르게 배열을 참조하는데 세미콜론(:)이 꼭 들어간다.
- 기존 프로그램을 짜 봤던 사람이라면 indexing은 쉽겠지만, slicing을 이해하는건 꽤나 까다롭고 처음엔 약간 변태적(?)인 문법이라는 생각이 들기도 한다.
- 이걸 한번에 이해할 수 있는 원리와 예제들을 한번 정리하고자 한다.
import numpy as np
test_list = [[1, 2, 5, 8],
[2, 3, 6, 9],
[3, 4, 7, 10],
[4, 5, 8, 11]] # 4 x 4 array
test_array = np.array(test_list, int)
print(test_array[1][2]) # 6 출력
print(test_array[1, 2]) # 동일하게 6 출력
test_array[1:2, :2] # 1번행 이상 / 2번행 미만, 2번 열 미만 출력
test_array[1, :2] # 동일하게 출력되지만, 위에는 2차원, 이 코드는 1차원으로 출력
test_array[:, 2:] # 모든 행, 2번 열 이후 출력
test_array[:, ::2] # 모든 행 + 모든 열을 2칸씩 띄워서
test_array[1::2, 0:4:3] # 1번 행부터 끝까지, 2행씩 띄워서 출력
# 0번 열부터 4번 미만 열까지, 3열씩 띄워서 출력
- 관련 글
2020/11/30 - [Python과 머신러닝/Python 데이터 수집] - NumPy의 ndarray 이해하기
2020/11/30 - [Python과 머신러닝/Python 데이터 수집] - ndarray.reshape - 크기 변환하기
1. Indexing
import numpy as np
test_list = [[1, 2, 5, 8],
[2, 3, 6, 9],
[3, 4, 7, 10],
[4, 5, 8, 11]] # 4 x 4 array
test_array = np.array(test_list, int)
print(test_array[1][2]) # 6 출력
print(test_array[1, 2]) # 동일하게 6 출력
- 위와 같이 4x4 배열을 ndarray 형태로 변환하였다고 하면, indexing은 대부분의 코드가 동작하는 것과 비슷하다.
- 각 차원 별로 대괄호 []를 써서 접근할 수 있다.
- 예제처럼 [1][2]로 접근하여 6이라는 값에 접근할 수 있다. (0-base indexing이기 때문에 첫 줄은 0번 줄이다)
- ndarray에서 다른 점이 있다면 [1, 2]로 접근을 해도 동일하게 접근이 가능한 점이다.
- 나는 C 기반의 코딩을 처음 시작했기 때문에 이 접근이 매우 낯설지만, 최소한 다른 프로그램을 볼 땐 동일하다는 걸 이해하기 위해 한 줄 추가로 정리했다.
2. Slicing 예제 #1
test_array[1:2, :2] # 1번행 이상 / 2번행 미만, 2번 열 미만 출력
- Indexing은 기타 코드/프로그램과 유사하다면, slicing은 난생처음 본 문법/기능이었다.
- Slicing이란 배열 중에서 원하는 부분만 뽑아 쓰기 위해 '잘라서 사용하는' 기능이다.
(그래서 이름이 slicing인 것 같다) - 위의 예제를 보면, 행의 위치에 1:2라는 것은 1이상 & 2 미만을 뜻한다.
- 행 위치에 있으니 1 이상 2 미만의 행을 의미하는 것이고, 같은 값이 콤마 뒤에 있었다면 1 이상 2 미만의 열이 되었을 것이다.
- 예제의 열 위치에 있는 :2는 2미만을 뜻한다. 즉, 2 미만의 모든 열을 slice 하라는 의미이다.
- test_array[1:2, :2]는 [[2,3]]의 값을 반환하게 된다.
3. Slicing 예제 #2
test_array[1, :2] # 동일하게 출력되지만, 위에는 2차원, 이 코드는 1차원으로 출력
- 행은 1번 행을 읽어온다.
- 열은 2 미만의 열을 읽어온다.
- 그렇기 때문에 데이터는 [2, 3]이 반환되어 1번 예제와 동일한 결과물 같아 보이지만,
- 2번 예제는 1차원 배열을 반환하고, 1번 예제는 2차원 배열을 반환하기 때문에 필요에 따라 골라서 사용해야 한다.
4. Slicing 예제 #3
test_array[:, 2:] # 모든 행, 2번 열 이후 출력
- 행에 세미콜론(:)만 있는 것은 '모든 행'을 뜻한다.
- 열의 2:는 2 이상의 모든 열을 뜻한다.
- 합치면 모든 행의 2열 이상의 데이터를 가져오라 는 의미가 된다.
- 결과물은 다음의 배열이 될 것이다
[[5, 8],
[6, 9],
[7, 10],
[8, 11]] # 4 x 2 array
5. Slicing 예제 #4
test_array[1::2, 0:4:3] # 1번 행부터 끝까지, 2행씩 띄워서 출력
# 0번 열부터 4번 미만 열까지, 3열씩 띄워서 출력
- 이건 예제로 정리해도 여전히 헷갈리는 개념이다.
- Start:End:Interval의 문법을 사용한다.
- 그리고 아무런 값이 없을 경우의 Default 값은 Start = 0, End = Total Row/Col count, Interval = 1이다.
- 행의 1::2는 1번부터 시작해서, 끝까지 출력하되, 2 행씩 건너뛰어서 출력하라는 것이다. (1번, 3번 행 출력)
- 열의 0:4:3은 0번 열부터 시작해서, 4번 열 미만까지 출력하되, 3열씩 건너뛰어서 출력하라는 것이다. (0번, 3번 열 출력)
- 결과적으로는 다음 2x2 배열이 나온다.
[[2,4],
[9,11]]
6. Slicing 예제 #5
test_array[:, ::2] # 모든 행 + 모든 열을 2칸씩 띄워서
- 이번 포스트의 마지막 예제이다.
- 모든 행의 데이터를 출력하라.
- 모든 열을 출력하되, 짝수번째 열들만 출력하라.
- 결과물은 다음 4x2배열이 될 것이다.
[[1, 5],
[2, 6],
[3, 7],
[4, 8]] # 4 x 2 array
7. 마무리
- Indexing은 비교적 단순하다. 각 dimension 별로 값을 주면, 해당 위치의 값을 반환해주는 것이 전부다.
- Slicing은 생각보다 간단하지 않지만, 원리만 이해하고 나면 쉽게 적용이 된다.
- Start:End:Interval의 문법으로 Slice 할 위치를 지정한다.
- 각 위치의 default 값은 0:Total count:1이다.
- 그래서 Start index를 생략하면 처음부터 전부라는 의미이고
- End Index를 생략하면 끝까지 전부라는 의미이고
- Interval을 생략하면 건너뛰지 않고 전부라는 의미이다.
- 처음 강의를 들을 때만 해도 참 어려웠지만, 정리하고 보니 참 잘 만들고 요긴하게 사용될 기능 같다.
- C에서 이런 걸 하려면 반복문을 몇개 써야 될지 생각만 해도 머리가 아파오는데, 그에 비해 위에 원리만 이해하면 NumPy의 ndarray는 아주 쉽게 사용하도록 만들었다.
관련 글
2020/11/30 - [Python과 머신러닝/Python 데이터 수집] - NumPy의 ndarray 이해하기
2020/11/30 - [Python과 머신러닝/Python 데이터 수집] - ndarray.reshape - 크기 변환하기
'Python과 머신러닝 > NumPy 데이터 분석' 카테고리의 다른 글
[Python.NumPy] ones_like, zeros_like, empty_like 함수 - Creation Function II (0) | 2020.12.05 |
---|---|
[Python.NumPy] arange/zeros/empty 함수의 차이 - Creation Function I (0) | 2020.12.04 |
[Python.NumPy] ndarray.reshape - 크기 변환하기 (0) | 2020.11.30 |
[Python.NumPy] ndarray 이해하기 (0) | 2020.11.30 |
[Python.NumPy] Y값 모델링 및 모델 평가 방법론 (0) | 2020.11.30 |