Note ≡ | np.stack과 np.concatenate
넘파이 객체를 합칠 때 사용하는 메서드로는 np.stack과 np.concatenate가 있습니다. 이 두 메서드는 차원의 유지 여부에 대한 차이가 있습니다. np.concatenate는 다음 그림과 같이 선택한 축(axis)을 기준으로 두 개의 배열을 연결합니다.
▲ 그림 2-27 np.concatenate(axis=1)
▲ 그림 2-28 np.concatenate(axis=0)
하지만 np.stack은 배열들을 새로운 축으로 합쳐 줍니다. 예를 들어 1차원 배열들을 합쳐서 2차원 배열을 만들거나 2차원 배열 여러 개를 합쳐 3차원 배열을 만듭니다. 따라서 반드시 두 배열의 차원이 동일해야 합니다.
▲ 그림 2-29 np.stack(axis=1)
▲ 그림 2-30 np.stack(axis=0)
코드를 통해서 둘의 차이를 다시 살펴봅시다.
먼저 임의의 넘파이 배열 a, b, c를 정의합니다. 이때 c는 다른 차원으로 정의합니다. 이후 같은 차원을 갖는 a와 b에 대해 np.concatenate와 np.stack을 적용해 보겠습니다.
a = np.array([[1, 2], [3, 4]]) ------ a.shape=(2, 2) b = np.array([[5, 6], [7, 8]]) ------ b.shape=(2, 2) c = np.array([[5, 6], [7, 8], [9, 10]]) ------ c.shape=(3, 2) print(np.concatenate((a, b), axis=0)) ------ shape=(4, 2) print('-------------------------------') print(np.stack((a, b), axis=0)) ------ shape=(2, 2, 2)
다음은 np.concatenate와 np.stack을 적용한 결과입니다. 차원이 같기 때문에 오류 없이 결과를 출력하고 있으며, np.stack의 경우에는 (2, 2, 2)로 차원이 변경된 것을 확인할 수 있습니다.
[[1 2] [3 4] [5 6] [7 8]] ------------------------------- [[[1 2] [3 4]] [[5 6] [7 8]]]
이번에는 서로 다른 차원을 합쳐 봅시다. 먼저 np.concatenate를 적용합니다.
print(np.concatenate((a, c), axis=0)) ------ shape=(5, 2)
그러면 다음과 같이 출력됩니다.
[[ 1 2] [ 3 4] [ 5 6] [ 7 8] [ 9 10]]
이번에는 np.stack을 적용합니다.
print(np.stack((a, c), axis=0))
np.stack은 합치려는 두 넘파이 배열의 차원이 다르기 때문에 오류가 발생합니다.
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-15-d547630d1e7e> in <module> ----> 1 print(np.stack((a, c), axis=0)) <__array_function__ internals> in stack(*args, **kwargs) e:\Anaconda3\envs\pytorch\lib\site-packages\numpy\core\shape_base.py in stack(arrays, axis, out) 425 shapes = {arr.shape for arr in arrays} 426 if len(shapes) != 1: --> 427 raise ValueError('all input arrays must have the same shape') 428 429 result_ndim = arrays[0].ndim + 1 ValueError: all input arrays must have the same shape