Python/Numpy

[Numpy] 배열 쌓기 : np.hstack, np.vstack, np.concatenate 차이 비교

jimmy_AI 2021. 12. 12. 13:33
반응형

넘파이 배열 쌓기 함수 : np.hstack, np.vstack, np.concatenate 비교

안녕하세요.

 

이번 글에서는 넘파이 array를 원하는 방향으로 쌓을 수 있는

np.hstack, np.vstack 그리고 np.concatenate의 기능 차이를 비교하고

실제 예시를 통하여 이해해보는 과정을 다루어보려고 합니다.

 

Numpy array 수평방향 쌓기 : np.hstack

먼저, np.hstack 함수를 통하여 두 배열을 쌓아보도록 하겠습니다.

 

먼저, 아래 코드처럼 간단하게 2 * 2 배열 두 개를 선언해보도록 하겠습니다.

import numpy as np

a = np.array([[1, 2], [3, 4]])
b = np.array([[8, 7], [6, 5]])

이제, 이 두 배열을 수평방향으로 먼저 쌓아보겠습니다.

두 배열을 ()로 묶어서 튜플 형태로 input으로 넣어주면 됩니다.

물론 3개 이상의 배열도 차원만 맞다면 동시에 쌓을 수 있습니다.

가로 방향으로 쌓여 2 * 4 차원의 배열이 완성된 것을 확인해볼 수 있었습니다.

 

Numpy array 수직방향 쌓기 : np.vstack

이번에는 수직 방향으로 array를 쌓아보도록 하겠습니다.

hstack과 마찬가지로 튜플 형태로 쌓을 배열을 순서대로 지정해서 넣어주면 됩니다.

이번에는 4 * 2 차원의 배열이 쌓인 결과로 생성된 것을 확인해보았습니다.

 

Numpy array 차원 지정해서 쌓기 : np.concatenate

차원을 원하는대로 지정해서 쌓을 수 있는 np.concatenate 함수를 다루어보겠습니다.

np.concatenate는 두 가지 인자를 input으로 넣어주면 되는데요,

첫 번째 인자는 위의 hstack, vstack 처럼 쌓을 배열 순서를 튜플 형태로 지정하면 되고,

두 번째 인자는 쌓을 축을 axis 인자로 지정해서 넣어주면 됩니다.

 

예를 들어, 2차원 배열의 경우, axis = 0이면 수직 방향을 의미해서 vstack과 동일하고,

axis = 1이면, 수평 방향을 의미해서 hstack과 동일한 결과를 나타냅니다.

또한, axis 인자는 None으로 지정해주어도 되는데, 이 때는 모든 원소를

1차원 배열에 편 상태로 반환하게 됩니다.

 

이제, np,concatenate 함수의 실제 결과를 비교해보도록 하겠습니다.

이 세 함수의 기능을 그림으로 간단히 도식화하여 요약하면 다음과 같습니다.

반응형

심화된 케이스 : 3차원 배열 예시

이번에는 3차원 배열에서의 예시를 살펴보며 위 세 함수의 심화된 사용 예시의

결과를 비교해보도록 하겠습니다.

 

먼저, 위와 마찬가지로 3차원 2 * 2 * 2 배열 두 개를 선언해보겠습니다.

a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = np.array([[[16, 15], [14, 13]], [[12, 11], [10, 9]]])

두 배열의 생김새는 위 이미지를 참고해주시면 됩니다.

 

먼저 hstack과 vstack의 결과를 비교해서 살펴보겠습니다.

결과가 다소 복잡해보입니다만, vstack은 axis = 0 기준, hstack은 axis = 1 기준이라는 것만

이해해주시면 해석하실 수 있을 것으로 생각됩니다.

 

즉, 2 * 2 * 2 배열 2 개를 쌓을 때, vstack은 2 * 2 배열이 4개 있는 것으로 보아 4 * 2 * 2 차원

으로 결과를 반환하게 되고, (axis = 0에 해당하는 차원의 숫자 증가)

 

hstack은 4 * 2 배열이 2개 있는 것으로 보는 2 * 4 * 2 차원으로 결과를 반환하게 됩니다.

(axis = 1에 해당하는 차원의 숫자 증가)

 

이제, np.concatenate 결과도 axis = 0, 1, None과 여기서는 axis = 2도 지원을 할테니

이 네가지 경우에 대한 결과를 비교하며 포스팅을 마무리해보도록 하겠습니다.

print('axis = 0의 경우, vstack과 동일 : shape (4, 2, 2)')
print(np.concatenate((a, b), 0))
print('axis = 1의 경우, hstack과 동일 : shape (2, 4, 2)')
print(np.concatenate((a, b), 1))
print('axis = 2의 경우 : shape (2, 2, 4)')
print(np.concatenate((a, b), 2))
print('axis = None의 경우 : shape (16, )')
print(np.concatenate((a, b), None))

axis = 2인 경우는 2 * 4 배열이 2개 있는 것으로 보는 상태이고(2 * 2 * 4 차원),

(axis = 2에 해당하는 차원의 숫자 증가)

 

axis = None인 경우는 1차언 배열에 모든 원소를 쫙 편 상태가 반환되었습니다.

 

concatenate 함수는 어렵게 생각하실 필요 없고, 배열을 합칠 때, 어떤 차원의 숫자가

증가할 것인지만 생각하시면 결과 이해도 쉬울 것으로 생각됩니다.

추가로, 차원의 배열이 커지더라도 vstack은 axis = 0 케이스,

hstack은 axis = 1 케이스인 것만 기억해주세요!