Python Numpy 강좌 : 제 11강 - 병합 및 분할
병합
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
c = np.hstack([a, b])
d = np.vstack([a, b])
print(a)
print(b)
print("--------")
print(c)
print(d)- 결과
- [[1 2]
[3 4]]
[[5 6]
[7 8]]
--------
[[1 2 5 6]
[3 4 7 8]]
[[1 2]
[3 4]
[5 6]
[7 8]]
numpy.hstack([배열1, 배열2])를 이용하여 배열1 우측에 배열2를 이어 붙일 수 있습니다.
numpy.vstack([배열1, 배열2])를 이용하여 배열1 하단에 배열2를 이어 붙일 수 있습니다.
hstack은 붙이는 방향(열)을 제외한 나머지 축의 길이가, vstack은 붙이는 방향(행)을 제외한 나머지 축의 길이가 같아야 합니다.
- Tip : 1차원 배열에
hstack을 사용하면 하나의 긴 1차원 배열이 되며,vstack을 사용하면 각 배열이 한 행이 되는 2차원 배열이 됩니다.
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
c = np.stack([a, b], axis=0)
d = np.stack([a, b], axis=1)
print(a)
print(b)
print("--------")
print(c)
print("--------")
print(d)- 결과
- [[1 2]
[3 4]]
[[5 6]
[7 8]]
--------
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
--------
[[[1 2]
[5 6]]
[[3 4]
[7 8]]]
numpy.stack([배열1, 배열2], axis=축)를 이용하여 지정한 축 위치에 새로운 축을 만들어 배열1과 배열2를 쌓을 수 있습니다.
hstack, vstack과 달리 결과 배열의 차원이 하나 증가하므로, (2, 2) 형태의 배열 두 개를 쌓으면 (2, 2, 2) 형태가 됩니다.
stack으로 쌓을 배열들은 형태(shape)가 모두 같아야 합니다.
축은 결과 배열의 차원 범위를 넘어갈 수 없으므로, 2차원 배열을 쌓을 경우 0 ~ 2 (또는 -3 ~ -1) 사이의 값을 사용할 수 있습니다.
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
c = np.dstack([a, b])
print(a)
print(b)
print("--------")
print(c)- 결과
- [[1 2]
[3 4]]
[[5 6]
[7 8]]
--------
[[[1 5]
[2 6]]
[[3 7]
[4 8]]]
numpy.dstack([배열1, 배열2])를 이용하여 깊이 방향(세 번째 축)으로 배열1과 배열2를 이어 붙일 수 있습니다.
2차원 배열의 경우, numpy.stack([a, b], axis=2)과 동일한 결과를 반환합니다.
- Tip :
dstack은 2차원 이하의 배열을 3차원으로 변환한 뒤 세 번째 축을 따라 이어 붙입니다. 이미 3차원인 배열은 차원이 증가하지 않고 세 번째 축의 길이만 늘어나므로,stack과 결과가 다릅니다.
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.tile(a, 2)
print(a)
print(b)- 결과
- [[1 2]
[3 4]]
[[1 2 1 2]
[3 4 3 4]]
numpy.tile(배열, 반복 횟수)를 이용하여 배열을 반복 횟수만큼 이어 붙일 수 있습니다.
반복 횟수에 정수를 입력할 경우 마지막 축(열 방향)으로 반복합니다. np.tile(a, (2, 1))과 같이 튜플을 입력하면 축마다 반복 횟수를 지정할 수 있으며, 이 경우 행 방향으로 두 번 반복됩니다.
특수 병합 메서드
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
c = np.c_[a, b]
d = np.r_[a, b]
print(a)
print(b)
print("--------")
print(c)
print(d)- 결과
- [[1 2]
[3 4]]
[[5 6]
[7 8]]
--------
[[1 2 5 6]
[3 4 7 8]]
[[1 2]
[3 4]
[5 6]
[7 8]]
numpy.c_[배열1, 배열2]를 이용하여 배열1 우측에 배열2를 이어 붙일 수 있습니다.
numpy.r_[배열1, 배열2]를 이용하여 배열1 하단에 배열2를 이어 붙일 수 있습니다.
np.c_와 np.r_은 함수가 아닌 인덱싱 객체이므로, 소괄호 ()를 사용하지 않고 대괄호 []를 사용합니다.
- Tip : 1차원 배열에
np.c_를 사용하면 각 배열을 열 벡터로 변환하여 이어 붙이므로,np.c_[[1, 2], [3, 4]]는(2, 2)형태의 배열을 반환합니다.
분할
import numpy as np
array = np.array([
[1, 2, 3, 4],
[5, 6, 7, 8]
])
a = np.hsplit(array, 2)
b = np.hsplit(array, (1, 3))
c = np.vsplit(array, 2)
print(a)
print("--------")
print(b)
print("--------")
print(c)- 결과
- [array([[1, 2],
[5, 6]]), array([[3, 4],
[7, 8]])]
--------
[array([[1],
[5]]), array([[2, 3],
[6, 7]]), array([[4],
[8]])]
--------
[array([[1, 2, 3, 4]]), array([[5, 6, 7, 8]])]
numpy.hsplit(배열, 개수 또는 구간)를 이용하여 배열을 수평 방향 또는 열(column) 단위로 분할합니다.
numpy.vsplit(배열, 개수 또는 구간)를 이용하여 배열을 수직 방향 또는 행(row) 단위로 분할합니다.
축을 따라 입력된 개수만큼 분할을 실행하며, 구간을 입력할 경우 해당 구간마다 잘라 n+1개의 배열이 생성됩니다.
import numpy as np
array = np.array([
[1, 2, 3, 4],
[5, 6, 7, 8]
])
a = np.split(array, 2, axis=0)
b = np.split(array, 2, axis=1)
print(a)
print(b)- 결과
- [array([[1, 2, 3, 4]]), array([[5, 6, 7, 8]])]
[array([[1, 2],
[5, 6]]), array([[3, 4],
[7, 8]])]
numpy.split(배열, 개수 또는 구간, 축)를 이용하여 배열을 축 방향으로 분할합니다.
지정된 축을 따라 입력된 개수만큼 분할을 실행하며, 구간을 입력할 경우 해당 구간마다 잘라 n+1개의 배열이 생성됩니다.
축을 입력하지 않으면 axis=0으로 분할하므로, hsplit은 axis=1, vsplit은 axis=0으로 분할하는 split과 같습니다.
import numpy as np
array = np.array([
[
[1, 2, 3, 4],
[5, 6, 7, 8]
],
[
[9, 10, 11, 12],
[13, 14, 15, 16]
]
])
a = np.dsplit(array, 2)
print(a)- 결과
- [array([[[ 1, 2],
[ 5, 6]],
[[ 9, 10],
[13, 14]]]), array([[[ 3, 4],
[ 7, 8]],
[[11, 12],
[15, 16]]])]
numpy.dsplit(배열, 개수 또는 구간)를 이용하여 배열을 깊이 방향(세 번째 축, axis=2)을 따라 분할합니다.
해당 함수는 3차원 이상의 배열에서만 작동합니다.
축을 따라 입력된 개수만큼 분할하며, 구간을 입력할 경우 해당 구간마다 잘라 n+1개의 배열이 생성됩니다.
균등하지 않은 분할
import numpy as np
array = np.arange(7)
print(np.array_split(array, 3))
np.split(array, 3)- 결과
- [array([0, 1, 2]), array([3, 4]), array([5, 6])]
ValueError: array split does not result in an equal division
numpy.split에 개수를 입력할 경우, 배열의 길이가 개수로 나누어 떨어져야 합니다. 길이가 7인 배열을 3개로 나누면 ValueError가 발생합니다.
numpy.array_split(배열, 개수, 축)을 이용하면 나누어 떨어지지 않아도 분할할 수 있습니다.
길이가 l인 배열을 n개로 나누면, 앞쪽 l % n개의 배열은 l // n + 1의 길이를, 나머지 배열은 l // n의 길이를 갖습니다.
연결과 쌓기의 차이
import numpy as np
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
c = np.concatenate([a, b], axis=0)
d = np.concatenate([a, b], axis=1)
e = np.stack([a, b], axis=0)
print(c.shape, d.shape, e.shape)
print(d)- 결과
- (4, 2) (2, 4) (2, 2, 2)
[[1 2 5 6]
[3 4 7 8]]
numpy.concatenate([배열1, 배열2], axis=축)을 이용하여 기존의 축을 따라 배열을 이어 붙일 수 있습니다.
axis=0은 vstack, axis=1은 hstack과 같은 결과를 반환하며, 결과 배열의 차원은 증가하지 않습니다.
반면, stack은 새로운 축을 만들어 배열을 쌓으므로 결과 배열의 차원이 하나 증가합니다.
- Tip :
hstack,vstack,dstack은 내부적으로concatenate를 사용하는 편의 함수입니다. 차원의 변화를 명확하게 표현하려면concatenate와stack을 사용하는 것이 좋습니다.
댓글 남기기