4.6.12 배열의 분리
4.6.12 유용한 함수 split()
① np.split() 개요
함수 np.split(ary)은 인자 ary를 여러 개의 부분 배열로 분리한다. 반환 값은 분리한 배열의 목록(list)이다.
numpy.split(ary, indices_or_sections, axis=0):
배열 ary를 축 axis에 따라 기준 indices_or_sections로 분할해 분할된 배열의 목록을 반환한다.
ary: 하위 배열로 분할할 배열indices_or_sections: 정수n인 경우, 배열은 축을 따라n개의 동일한 배열로 분할되는데, 이러한 분할이 불가능하면 오류가 발생한다. 1차원 1D Array 또는 1차원 배열인 경우,indices_or_sections가 정렬된 정수의 1차원 배열인 경우, 해당 축을 따라 배열이 분할되는 위치를 나타낸다. 예를 들어,[2, 3]은 다음과 같이ary[:2],ary[2:3],ary[3:]으로 분할된다. 첨자가 축을 따른 배열의 크기를 초과하는 경우 그에 따라 빈 하위 배열이 반환된다.axis=0: 기본은 0이며, 분할하는 축
l = np.split(a, axis=0)는 다음에 학습할 np.vsplit(a)와 같다.

l = np.split(a, axis=1)는 다음에 학습할 np.hsplit(a)와 같다.

② np.split(ary, n)
다음 실수 9개로 구성된 벡터 x가 있다.
import numpy as np
x = np.arange(9.0)
x
출력:
array([0., 1., 2., 3., 4., 5., 6., 7., 8.])
s = np.split(x, 3)
s
출력:
[array([0., 1., 2.]), array([3., 4., 5.]), array([6., 7., 8.])]
np.split()의 결과는 분리된 배열 리스트이다.
print(type(s))
print(s[0])
출력:
<class 'list'>
[0. 1. 2.]
9개의 원소를 4개로 분리하면 동등하게 떨어지지 않아 오류가 발생한다.
np.split(x, 4)
오류:
ValueError: array split does not result in an equal division
③ np.split(ary, [i, j, k, …])
함수 np.split(a, [2, 6])으로 다음 그림처럼 10개의 요소로 구성된 배열을 원래 순서대로 각각 2, 4, 3개의 요소로 구성된 3개의 배열로 분리할 수 있다.
![np.split(x, [2, 6])의 이해](img/page_035.png)
여기서 [2, 6]이란 분할하는 첨자를 말한다. 즉 [2, 6]은 2, 6으로 구분하는 3개의 슬라이싱인 x[:2], x[2:6], x[6:]의 배열로 분할한다.
위 그림의 x는 다음과 같다.
x = np.arange(1, 10)
x
출력:
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
다음 코드로 순서대로 원소가 2개, 4개, 3개인 배열로 분리할 수 있다.
np.split(x, [2, 6])
출력:
[array([1, 2]), array([3, 4, 5, 6]), array([7, 8, 9])]
원소 6개인 벡터 y가 있다.
y = np.arange(10, 61, 10)
y
출력:
array([10, 20, 30, 40, 50, 60])
함수 np.split(y, [2, 3, 4])로 분리하면 다음 그림처럼 첨자 2, 3, 4로 4개의 부분 배열로 반환된다.
![np.split(y, [2, 3, 4])에서 인자 [2, 3, 4] 의미](img/page_036.png)
다음은 위 그림을 구현한 코드이다.
np.split(y, [2, 3, 4])
출력:
[array([10, 20]), array([30]), array([40]), array([50, 60])]
다음 코드처럼 분할 첨자가 [2, 3, 4, 6]이면 마지막으로 분할되는 배열은 빈(empty) 배열이다. 그러므로 반환 목록 마지막이 array([], dtype=int32)이다.
np.split(y, [2, 3, 4, 6])
출력:
[array([10, 20]),
array([30]),
array([40]),
array([50, 60]),
array([], dtype=int32)]
위 결과를 확인하기 위해 슬라이싱 y[4:6]의 결과를 알아보자.
y[4:6]
출력:
array([50, 60])
이제 마지막 슬라이싱인 y[6:]의 결과를 알아보자. 바로 빈 배열임을 알 수 있다.
y[6:]
출력:
array([], dtype=int32)
④ 다차원 배열의 np.hsplit(ary, indices_or_sections)
다음 모양 (2, 12)의 2차원 배열 a가 있다.
a = np.arange(24).reshape(2, 12)
a
출력:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]])
배열 a를 축 1 방향(수평으로 이동하며)으로 3개로 분리하면 12/3 = 4이므로, 4개의 열로 구성된 분할 배열 목록인 다음 결과가 표시된다.
np.split(a, 3, axis=1)
출력:
[array([[ 0, 1, 2, 3],
[12, 13, 14, 15]]),
array([[ 4, 5, 6, 7],
[16, 17, 18, 19]]),
array([[ 8, 9, 10, 11],
[20, 21, 22, 23]])]
마찬가지로, 배열 a를 축 1 방향으로 4개로 분리하면 다음 결과가 나온다.
np.split(a, 4, axis=1)
출력:
[array([[ 0, 1, 2],
[12, 13, 14]]),
array([[ 3, 4, 5],
[15, 16, 17]]),
array([[ 6, 7, 8],
[18, 19, 20]]),
array([[ 9, 10, 11],
[21, 22, 23]])]
그러나, 배열 a를 축 1 방향으로 5개로 분리하면 12/5가 동등하게 떨어지지 않으므로 오류가 발생한다.
np.split(a, 5, axis=1)
오류:
ValueError: array split does not result in an equal division
다음은 슬라이싱 인자로 분리한 결과이다.
np.split(a, [3, 5, 8], axis=1)
출력:
[array([[ 0, 1, 2],
[12, 13, 14]]),
array([[ 3, 4],
[15, 16]]),
array([[ 5, 6, 7],
[17, 18, 19]]),
array([[ 8, 9, 10, 11],
[20, 21, 22, 23]])]
참고로 직접 슬라이싱 a[:, :3]의 결과는 위 결과 첫 항목과 같다.
a[:, :3]
출력:
array([[ 0, 1, 2],
[12, 13, 14]])
또한, 슬라이싱 a[:, 8:]의 결과는 위 결과 마지막 항목과 같다.
a[:, 8:]
출력:
array([[ 8, 9, 10, 11],
[20, 21, 22, 23]])
다음은 모양 (6, 4)의 2차원 배열 b이다.
b = np.arange(24).reshape(6, 4)
b
출력:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])
배열 b를 축 0 방향(수직 방향)으로 3개로 나누면 다음 결과가 나온다. axis는 기본이 0이므로 생략 가능하다.
np.split(b, 3, axis=0)
출력:
[array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7]]),
array([[ 8, 9, 10, 11],
[12, 13, 14, 15]]),
array([[16, 17, 18, 19],
[20, 21, 22, 23]])]
축 0 방향(수직 방향)으로 슬라이싱 첨자 [2, 4, 6]으로 나누면 다음 결과가 나온다.
np.split(b, [2, 4, 6], axis=0)
출력:
[array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7]]),
array([[ 8, 9, 10, 11],
[12, 13, 14, 15]]),
array([[16, 17, 18, 19],
[20, 21, 22, 23]]),
array([], shape=(0, 4), dtype=int32)]