서론
배열을 연결하는 부분에서는 다량의 실습용 코드들이
등장하게 됩니다. 사실 이전부터 원래도 많긴 했지만 더욱 많아지게 됩니다!
이론을 열심히 배우는 것도 중요하겠습니다.
하지만 손으로 직접 쓰는 것만큼 더 좋은 공부방법도 없겠죠?!
직접 해보는 것과 열심히 보는 것은 다릅니다.
짜릿한 익스트림 자전거 처럼요!
자 먼저 concatenate 부터 시작합니다 🙌
배열의 연결
행의 수나 열의 수가 같은 두 개 이상의 배열을 연결하여
더 큰 배열을 생성합니다.
리스트 자체는 + 연산자를 통해 합치는 것이 가능합니다.
[1,2] + [3,4]
[1, 2, 3, 4]
다만, 이를 ndarray에서 진행하면, 벡터화 연산이 되어
버립니다.
arr1 = np.arange(1,4)
arr2 = np.arange(4,7)
arr1, arr2
(array([1, 2, 3]), array([4, 5, 6]))
arr1+arr2
array([5, 7, 9])
그렇다면 어떻게 배열을 연결시킬 수 있을까요?
무려, 8가지나 되는 방법들이 있습니다.
먼저 concatenate ( n, axis)를 사용합니다.
arr = np.concatenate([arr1,arr2])
arr #1차원 배열 연결
array([1, 2, 3, 4, 5, 6])
concatenate
미국식[kɑnkǽtənèit] 영국식[kɔn-]발음
타동사 1 사슬같이 잇다; 연쇄시키다; <사건 등을> 결부[연결]시키다, 연관시키다
형용사 1 연쇄된, 이어진, 연결된
단어 자체가 연쇄시킨다는 뜻이죠.
2차원 배열의 연결도 가능할까요?
2차원 배열 연결
arr1 = np.arange(1,5).reshape(2,2)
#np.array([[1,2],[3,4]])
arr2 = np.arange(5,9).reshape(2,2)
#np.array([[5,6],[7,8]])
arr1, arr2
(array([[1, 2],
[3, 4]]), array([[5, 6],
[7, 8]]))
가능합니다.
위에서는 언급하지 않았지만 열/행의 기준을
수정시키는 것도 됩니다. axis를 사용해요.
arr = np.concatenate([arr1, arr2])
arr # 행을 기준으로 연결
array([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
arr = np.concatenate([arr1, arr2],axis= 1)
arr # 열을 기준으로 연결
array([[1, 2, 5, 6],
[3, 4, 7, 8]])
자 행과 열을 붙인 것이 보이시나요?
그다음으로는 수평과 수직으로 붙이는 함수가 있습니다.
hstack
행의 수가 같은 두 개 이상의 배열을 옆으로 연결하여
열의 수가 늘어난 배열을 만듭니다.
🤔 연결할 배열은 하나의 리스트(튜플)에 담아서 메서드에 넣어줘야 합니다.
horizontal = 수평/ 가로
vertical = 수직/ 세로
hstack은 horizontal의 앞글자를 딴 것이죠!
직접 붙여보겠습니다.
a1 = np.ones((2,3)) # 2 x 3
a1
a2 = np.zeros((2,2)) # 2 x 2
a2
array([[1., 1., 1.],
[1., 1., 1.]])
array([[0., 0.],
[0., 0.]])
np.hstack([a2,a1])
array([[0., 0., 1., 1., 1.],
[0., 0., 1., 1., 1.]])
이렇게 수평으로 배열이 붙여지게 됩니다.
물론 좌우로 붙기 때문에, 행의 수는 같아야겠죠?
vstack
vstack도 hstack에 특별히 바뀌는 점은 없습니다.
수직으로 증가하게 됩니다.
b1 = np.ones((2,3)) # 2x3
b2 = np.zeros((3,3)) # 3x3
b1, b2
(array([[1., 1., 1.],
[1., 1., 1.]]),
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]]))
원래 줄바꿈이 없지만, 보기 편하게 하기 위해
줄바꿈을 넣었습니다.
np.vstack([b1,b2])
array([[1., 1., 1.],
[1., 1., 1.],
[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
수직으로 늘어납니다.
dstack
세번째 축, 깊이가 늘어납니다.
즉, 행이나 열이 아닌 depth가 늘어나는 방향으로 배열을 합칩니다
행렬을 보겠습니다.
c1 = np.ones((3,4))
c2 = np.zeros((3,4))
c1, c2
(array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]), array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]]))
c1과 c2를 dstack으로 합쳐볼까요.
np.dstack([c1,c2])
array([[[1., 0.],
[1., 0.],
[1., 0.],
[1., 0.]],
[[1., 0.],
[1., 0.],
[1., 0.],
[1., 0.]],
[[1., 0.],
[1., 0.],
[1., 0.],
[1., 0.]]])
자, 배열을 90도로 회전시킨 상태에서
합친 것처럼 3차원 배열로 합쳐졌습니다.
가장 안쪽의 원소의 차원이 증가합니다.
np.dstack([c1,c2]).shape
(3, 4, 2)
다른 stack들과 차이를 볼까요?
np.hstack([c1,c2])
array([[1., 1., 1., 1., 0., 0., 0., 0.],
[1., 1., 1., 1., 0., 0., 0., 0.],
[1., 1., 1., 1., 0., 0., 0., 0.]])
np.vstack([c1,c2])
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
그외의 stack도 있습니다.
stack
stack은 dstack의 기능을 확장한 것입니다!
dstack처럼 3차원 축으로 연결되는 것은 아니고
사용자가 지정한 축으로 배열을 연결합니다.
axis가 0일 때
c = np.stack([c1, c2])
c
array([[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]]])
shape 확인
c.shape
(2, 3, 4)
axis가 1일 때
c = np.stack([c1,c2], axis =1)
c, c.shape
(array([[[1., 1., 1., 1.],
[0., 0., 0., 0.]],
[[1., 1., 1., 1.],
[0., 0., 0., 0.]],
[[1., 1., 1., 1.],
[0., 0., 0., 0.]]]), (3, 2, 4))
axis가 2일 때
(dstack과 유사합니다)
c = np.stack([c1,c2], axis =2)
c, c.shape
(array([[[1., 0.],
[1., 0.],
[1., 0.],
[1., 0.]],
[[1., 0.],
[1., 0.],
[1., 0.],
[1., 0.]],
[[1., 0.],
[1., 0.],
[1., 0.],
[1., 0.]]]), (3, 4, 2))
r_ 인덱서
이 연결방법도 자주 쓰이는 방식입니다.
인덱서라는 특수한 메서드를 처음 선보이는데요?
hstack처럼 배열을 좌~우로 연결합니다.
다만 메서드 소괄호 "( )" 를 사용하지 않고
대괄호 " [ ] " 을 사용합니다. (Bracket)
배열 생성
np.arange(1,4), np.arange(4,7)
(array([1, 2, 3]), array([4, 5, 6]))
np.r_[np.arange(1,4),np.arange(4,7)]
array([1, 2, 3, 4, 5, 6])
c_ 인덱서
r_ 인덱서와 다르게 배열의 차원을 올리고,
좌우로 연결합니다.
차원 증가시킴 → 그 후에 붙이는 것이죠
c = np.c_[np.arange(1,4),np.arange(4,7)]
c,c.shape
(array([[1, 4],
[2, 5],
[3, 6]]), (3, 2))
마지막 tile 입니다.
tile
tile은 동일한 배열을 반복해서 연결해주는데
배열과 횟수를 써주면 반복됩니다 (다른 배열을 쓰지 않습니다)
a = np.arange(6).reshape(2,-1)
a
array([[0, 1, 2],
[3, 4, 5]])
np.tile(a,2) # 반복할 배열, 반복할 횟수
array([[0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5]])
말 그대로 타일처럼 반복된 패턴을
배열로 깔아주는 것이죠!
np.tile(a,((3,2))) # 행으로 3번, 열로 2번
array([[0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5],
[0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5],
[0, 1, 2, 0, 1, 2],
[3, 4, 5, 3, 4, 5]])
좋습니다.
연결의 반대기능인 분할 함수입니다.
배열 분할
split과 hsplit, vsplit을 사용합니다.
arr = np.arange(1,7)
arr
array([1, 2, 3, 4, 5, 6])
3개의 배열로 쪼개보겠습니다.
newarr = np.array_split(arr, 3)
newarr
[array([1, 2]), array([3, 4]), array([5, 6])]
2차원 배열부터는 연결했을때처럼,
vsplit과 hsplit으로 분할이 가능합니다.
arr = np.arange(1,13).reshape(3,4)
arr
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])
split(배열, 쪼갤 횟수, 축의 기준 (0은 행, 1은 열)
newarr = np.array_split(arr,2,axis =1)
newarr
[array([[ 1, 2],
[ 5, 6],
[ 9, 10]]), array([[ 3, 4],
[ 7, 8],
[11, 12]])]
hsplit으로 똑같이 진행해보겠습니다.
np.hsplit(arr,2)
[array([[ 1, 2],
[ 5, 6],
[ 9, 10]]), array([[ 3, 4],
[ 7, 8],
[11, 12]])]
vsplit은 수평 방향으로 쪼개줍니다.
np.vsplit(arr,3)
[array([[1, 2, 3, 4]]), array([[5, 6, 7, 8]]), array([[ 9, 10, 11, 12]])]
이상입니다!
이렇게 해서 배열의 연결과 분할까지를 보았습니다.
다음에는 2차원 그리드 포인트, 기초적인 벡터화 연산을 다시 보겠습니다.
😇😇
'Programming Language > Python_library' 카테고리의 다른 글
파이썬_응용단계 ep.7 정렬과 통계 (0) | 2022.12.11 |
---|---|
파이썬_응용단계 ep.6 배열의 연산 (0) | 2022.12.11 |
파이썬_응용단계 ep.4 생성과 변형, 전치 (2) | 2022.12.08 |
파이썬_응용단계 ep.3 배열 깎는 조각가 (0) | 2022.12.08 |
파이썬_응용단계 ep.2 Numpy 튜토리얼 (2) | 2022.12.07 |