column 방향으로 / row 방향으로 array를 합칠 것인지 정하는 API이다
import numpy as np
a = np.random.randint(0, 10, (4,)) [4 2 1 0]
b = np.random.randint(0, 10, (4,)) [6 7 2 2]
vstack = np.vstack([a,b])
shape : (2,4)
[[4 2 1 0]
[6 7 2 2]]
hstack = np.hstack([a,b])
shape : (8,)
[4 2 1 0 6 7 2 2]
또 다른 예시
import numpy as np
a = np.random.randint(0, 10, (1,3)) [[0 8 7]]
b = np.random.randint(0, 10, (1,3)) [[9 2 6]]
vstack = np.vstack((a,b))
shape : (2,3)
[[0 8 7]
[9 2 6]]
hstack = np.hstack((a,b))
shape : (1,6)
[[0 8 7 9 2 6]]
여기서는 hstack할시 1이라는 차원값이 유지된다는 차이점이 있다.
또다른 예시
import numpy as np
a = np.random.randint(0, 10, (3,1)) [[5][0][8]]
b = np.random.randint(0, 10, (3,1)) [[4][9][7]]
vstack = np.vstack((a,b))
shape : (6,1)
[[5]
[0]
[8]
[4]
[9]
[7]]
hstack = np.hstack((a,b))
shape : (3,2)
[[5 4]
[0 9]
[8 7]]
조심할 것
(3,4)의 ndarray에 쌓기 위해서는
Making Datasets
import numpy as np
dataset = np.empty((0,4))
for iter in range(5):
data_sample = np.random.uniform(0, 5, (1,4))
dataset = np.vstack((dataset, data_sample))
(4, )의 데이터를 쌓아나갈 예정이라고 생각해보자. 이때 데이터를 쌓을 수 있는 위치를 잡아준다고 생각해주면 된다. dataset에다가 data_sample을 한 줄씩 더해준다.
Making toy dataset
import numpy as np
dataset_tmp = list()
for iter for range(100):
data_sample = np.random.uniform(0,5,(1,4))
dataset_tmp.append(data_sample)
dataset = np.vstack(dataset_tmp)
print(f'final shape: {dataset.shape}") (100,4)
import numpy as np
a = np.random.randint(0, 10, (3, )) [1 9 9]
b = np.random.randint(0, 10, (4, )) [2 6 9 4]
concat = np.concatenate([a,b]) [1 9 9 2 6 9 4]
concat0 = np.concatenate([a,b],axis = 0) [1 9 9 2 6 9 4]
import numpy as np
a = np.random.randint(0, 10, (1,3))
b = np.random.randint(0, 10, (1,3))
axis0 = np.concatenate([a,b], axis = 0) (2,3)
axis1 = np.concatenate([a,b], axis = 1) (1,6)
axis_n1 = np.concatenate([a,b], axis=-1) (1,6)
위와 같은 경우 axis 0에 대해 concat한다는 것은 row를 따라 stacking을 한다는 의미와 동일하다. 즉 가독성을 위해서는 np.vstack을 쓰는 것이 더 낫다
axis 1도 마찬가지이다. 가독성을 위해서는 np.hstack이 낫다.
import numpy as np
a = np.random.randint(0, 10, (3,4))
b = np.random.randint(0, 10, (3,2))
concat = np.concatenate([a,b], axis = 1) (3,6)
(3,4)와 (3,2)는 row의 크기가 같고 column의 크기가 다르다. 그러므로 axis 1에 대해서만 연산이 가능하며 axis 0에 대해서는 오류가 발생한다.
concatenation은 고차원 텐서를 연산할 때 유용하다
import numpy as np
a = np.random.randint(0, 10, (3,4,5))
b = np.random.randint(0, 10, (10,4,5))
concat0 = np.concatenate([a,b], axis=0)
-> (13,4,5)
나머지 차원이 같을 때 하나의 선택된 차원에 대해서 더할 수 있는 등 vstack, hstack보다 범용적으로 사용할 수 있다.
Making toy dataset
import numpy as np
dataset_tmp = list()
for iter in range(100):
data_sample = np.random.uniform(0,5,(1,4))
data_tmp.append(data_sample)
concat = np.concatenate(dataset_tmp, axis = 0)
-> (100,4)
for iter in range(100):
data_sample = np.random.uniform(0,5,(4,1))
data_tmp.append(data_sample)
concat = np.concatenate(dataset_tmp, axis = 1)
-> (4,100)
지금까지는 새로운 차원을 만들면서 합치지는 않았다. 지금까지는 ndarray에 존재하는 차원을 기준으로 stacking을 한다.
import numpy as np
R = np.random.randint(0,10, (100,200))
G = np.random.randint(0,10, size = R.shape)
B = np.random.randint(0,10, size = R.shape)
image = np.dstack([R,G,B]) -> (100, 200, 3)
dstack은 dimension stack이다. 그리고 제일 안쪽 차원에 새로운 차원이 만들어진다.
import numpy as np
R = np.random.randint(0,10, (100,200,3))
G = np.random.randint(0,10, size = R.shape)
B = np.random.randint(0,10, size = R.shape)
image = np.dstack([R,G,B]) -> (100, 200, 9)
이런 결과가 나오므로 concatenation을 사용하는 것이 더 나을 것 같다.
import numpy as np
R = np.random.randint(0,10, (100,200,300))
G = np.random.randint(0,10, (100,200,300))
B = np.random.randint(0,10, (100,200,300))
np.stack([R,G,B], axis = 0) -> (3, 100, 200,300)
np.stack([R,G,B], axis = 1) -> (100, 3, 200,300)
stack은 axis를 표기하면 원하는 위치에 새로운 차원을 만들면서 stack이 가능하다. vstack, hstack, dstack은 행렬을 다룰 때 사용한다. Concatenation과 stack은 더 고차원을 다룰 때 사용한다.