인덱싱
인덱싱은 파이썬 list와 크게 다르지 않다.
1차원 배열
arr = np.arange(10)
arr[2]
다차원 배열
arr_np = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr_np[0][1]
arr_np[0, 1]
다차원 배열은 파이썬 list와 같이 [][]... 형태로 인덱스를 찾아갈수도 있고 [x, x, x....] 형태로 찾아갈수도 있다.
또한 다차원 배열의 각 인덱스 요소는 numpy 배열이다. 즉
arr_np[1]인 [4, 5, 6] 배열에 대해 이런 연산이 가능하다.
슬라이싱
1차원 배열
arr_np = np.array([1, 2, 3, 4, 5])
arr_slice = arr_np[2:4]
슬라이싱도 파이썬 list와 형태는 크게 다르지 않은데, 데이터 복사가 이루어지지 않는다는 점이 다르다.
파이썬 list
arr_py = [1, 2, 3, 4, 5]
arr_py_slice = arr_py[:]
arr_py_slice[1] = 100
arr_py_slice는 arr_py와는 독립적인 변수이기 때문에 arr_py_slice의 값을 변경한다고 해서 arr_py에 직접 영향을 주지 않는다.
numpy 배열
arr = np.array([1, 2, 3, 4, 5])
arr_slice = arr[:]
arr_slice[1] = 100
numpy 배열의 슬라이싱은 원본 배열의 view처럼 사용되고, view의 변경은 그대로 원본 배열에 반영된다.
이는 numpy의 설계 목적과 관련이 있다. numpy는 대용량 데이터의 처리를 염두에 두고 설계되었기 때문에, 메모리 초과 등 성능 문제를 고려해 데이터 복사를 신중히 사용하도록 한 것이다.
만약 파이썬 리스트 슬라이싱처럼 데이터를 복사하고 싶다면, copy 메서드를 사용한다.
다차원 배열
numpy가 정말 좋은 라이브러리라고 생각하는 기능 중 하나다. 먼저 이런 배열이 있다.
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
위 2차원 배열은 다음과 같은 형태로 인덱스를 구분할 수 있다.
1 [0, 0] | 2 [0, 1] | 3 [0, 2] |
4 [1, 0] | 5 [1, 1] | 6 [1, 2] |
7 [2, 0] | 8 [2, 1] | 9 [2, 2] |
10 [3, 0] | 11 [3, 1] | 12 [3, 2] |
numpy의 벡터화를 이용해, for문을 사용하지 않고도 여러 칸의 배열을 한꺼번에 선택할 수 있다.
형태는 [row 슬라이싱, column 슬라이싱] 형태이다.
1 [0, 0] | 2 [0, 1] | 3 [0, 2] |
4 [1, 0] | 5 [1, 1] | 6 [1, 2] |
7 [2, 0] | 8 [2, 1] | 9 [2, 2] |
10 [3, 0] | 11 [3, 1] | 12 [3, 2] |
4, 5, 7, 8만을 선택하고 싶다면?
arr[1:3, :2]
arr[1:3]에서 4,5,6이 포함된 1row와 7,8,9가 포함된 2row가 선택되고, [:2]에서 6, 9가 잘려나가게 된다. row, column으로 슬라이싱을 바라보면 이해가 빠를듯 하다.
1차원 배열의 슬라이싱처럼 이렇게 slicing한 다차원 배열도 벡터화가 되어 있기 때문에 연산 등 편리한 기능을 그대로 사용할 수 있다.
'파이썬 > numpy' 카테고리의 다른 글
Numpy 6. Boolean 2, Numpy 조건 연산자 (0) | 2020.10.28 |
---|---|
Numpy 5. boolean (0) | 2020.10.26 |
Numpy 3. Numpy 배열의 산술연산 (0) | 2020.10.23 |
numpy 2. ndarray (0) | 2020.10.23 |
Numpy 1. numpy의 장점 (0) | 2020.10.21 |