2022년 7월 19일 화요일

python numpy 배열/행렬을 붙이기 np.r_, np.c_, np.hstack, np.vstack, np.concatenate

 numpy 를 사용하다보면 배열과 행렬을 여기저기에 붙이는 작업을 자주 합니다. 해당 내용을 정리해보겠습니다.

여기에선 행렬을 붙이는 예제를 들고자 합니다.

들어가기에 앞서 여기에서는 특별한 설명 없이 배열이라고하면 1차원 배열을 의미하고 행렬은 2차원 배열로 설명하겠습니다.

기본 동작

(3,2) 크기의 행렬 2개를 붙인다고 할 때 사용하는 함수는 아래와 같습니다. 



실제 동작 결과입니다.

>>> import numpy as np
>>> a = np.array([[1, 2], [3, 4], [5, 6]])
>>> a.shape
(3, 2)
>>> a
array([[1, 2],
       [3, 4],
       [5, 6]])
>>> b = np.array([[11, 12], [13, 14], [15, 16]])
>>> b
array([[11, 12],
       [13, 14],
       [15, 16]])

# 아래쪽으로 붙이기
>>> np.r_[a,b]
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [11, 12],
       [13, 14],
       [15, 16]])

>>> np.vstack([a,b])
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [11, 12],
       [13, 14],
       [15, 16]])
	   
>>> np.concatenate((a,b),axis=0)
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [11, 12],
       [13, 14],
       [15, 16]])

# 오른쪽으로 붙이기
>>> np.c_[a,b]
array([[ 1,  2, 11, 12],
       [ 3,  4, 13, 14],
       [ 5,  6, 15, 16]])
	   
>>> np.hstack([a,b])
array([[ 1,  2, 11, 12],
       [ 3,  4, 13, 14],
       [ 5,  6, 15, 16]])
	   
>>> np.concatenate((a,b),axis=1)
array([[ 1,  2, 11, 12],
       [ 3,  4, 13, 14],
       [ 5,  6, 15, 16]])


여러가지 방식으로 붙여보기

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> import numpy as np
>>> a = np.array([[1, 2], [3, 4], [5, 6]])
>>> a.shape
(3, 2)
>>> b = np.array([21, 22, 23])
>>> b.shape()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object is not callable
>>> b.shape
(3,)
>>> b
array([21, 22, 23])
>>> np.r_[a,b]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/work/myenv38/lib/python3.8/site-packages/numpy/lib/index_tricks.py", line 412, in __getitem__
    res = self.concatenate(tuple(objs), axis=axis)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
>>> np.vstack([a,b])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in vstack
  File "/work/myenv38/lib/python3.8/site-packages/numpy/core/shape_base.py", line 282, in vstack
    return _nx.concatenate(arrs, 0)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 2 and the array at index 1 has size 3
>>> np.concatenate((a,b),axis=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
>>> np.c_[a,b]
array([[ 1,  2, 21],
       [ 3,  4, 22],
       [ 5,  6, 23]])
>>> np.hstack([a,b])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in hstack
  File "/work/myenv38/lib/python3.8/site-packages/numpy/core/shape_base.py", line 345, in hstack
    return _nx.concatenate(arrs, 1)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
>>> np.concatenate((a,b),axis=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> b = np.array([[21], [22], [23]])
>>> b
array([[21],
       [22],
       [23]])
>>> b.shape
(3, 1)
>>> np.r_[a,b]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/work/myenv38/lib/python3.8/site-packages/numpy/lib/index_tricks.py", line 412, in __getitem__
    res = self.concatenate(tuple(objs), axis=axis)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 2 and the array at index 1 has size 1
>>> np.vstack([a,b])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in vstack
  File "/work/myenv38/lib/python3.8/site-packages/numpy/core/shape_base.py", line 282, in vstack
    return _nx.concatenate(arrs, 0)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 2 and the array at index 1 has size 1
>>> np.concatenate((a,b),axis=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 2 and the array at index 1 has size 1
>>> np.c_[a,b]
array([[ 1,  2, 21],
       [ 3,  4, 22],
       [ 5,  6, 23]])
>>> np.hstack([a,b])
array([[ 1,  2, 21],
       [ 3,  4, 22],
       [ 5,  6, 23]])
>>> np.concatenate((a,b),axis=1)
array([[ 1,  2, 21],
       [ 3,  4, 22],
       [ 5,  6, 23]])
>>>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> b = np.array([21, 22])
>>> b.shape
(2,)
>>> b
array([21, 22])
>>> np.r_[a,b]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/work/myenv38/lib/python3.8/site-packages/numpy/lib/index_tricks.py", line 412, in __getitem__
    res = self.concatenate(tuple(objs), axis=axis)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
>>> np.vstack([a,b])
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [21, 22]])
>>> np.concatenate((a,b),axis=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
>>> np.c_[a,b]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/work/myenv38/lib/python3.8/site-packages/numpy/lib/index_tricks.py", line 412, in __getitem__
    res = self.concatenate(tuple(objs), axis=axis)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 0, the array at index 0 has size 3 and the array at index 1 has size 2
>>> np.hstack([a,b])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in hstack
  File "/work/myenv38/lib/python3.8/site-packages/numpy/core/shape_base.py", line 345, in hstack
    return _nx.concatenate(arrs, 1)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
>>> np.concatenate((a,b),axis=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
>>>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> b = np.array([[21, 22]])
>>> b.shape
(1, 2)
>>> b
array([[21, 22]])
>>> np.r_[a,b]
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [21, 22]])
>>> np.vstack([a,b])
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [21, 22]])
>>> np.concatenate((a,b),axis=0)
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [21, 22]])
>>> np.c_[a,b]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/work/myenv38/lib/python3.8/site-packages/numpy/lib/index_tricks.py", line 412, in __getitem__
    res = self.concatenate(tuple(objs), axis=axis)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 0, the array at index 0 has size 3 and the array at index 1 has size 1
>>> np.hstack([a,b])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in hstack
  File "/work/myenv38/lib/python3.8/site-packages/numpy/core/shape_base.py", line 345, in hstack
    return _nx.concatenate(arrs, 1)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 0, the array at index 0 has size 3 and the array at index 1 has size 1
>>> np.concatenate((a,b),axis=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input array dimensions for the concatenation axis must match exactly, but along dimension 0, the array at index 0 has size 3 and the array at index 1 has size 1
>>>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


1차원 배열과 2차원 배열의 표현법 다름을 이해

위의 결과를 보면 2차원 배열에 붙일때는 2차원 배열로 크기를 맞춰서 붙이는것이 제일 제대로 동작합니다. 1차원 배열로 붙이더라도 붙는 함수가 있긴 하지만 1차원형태로 만들어 주는것이 좋습니다. 

아래는 비슷하게 생겼지만 아래 표현법을 익히는 것이 중요합니다. 

1차원 배열 : [21, 22]
2차원 배열 가로 : [[21, 22]]
2차원 배열 세로 : [[21], [22], [23]]

또한 가로 세로 변경은 .T 를 붙여서 전환이 가능합니다. (전치행렬:대각선을 기준으로 뒤집음)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1차원 배열
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> b = np.array([21, 22])
>>> b.shape
(2,)
>>> b
array([21, 22])
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2차원 배열 가로
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> b = np.array([[21, 22]])
>>> b.shape
(1, 2)
>>> b
array([[21, 22]])
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2차원 배열 세로
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> b = np.array([[21], [22], [23]])
>>> b
array([[21],
       [22],
       [23]])
>>> b.shape
(3, 1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
전치 행렬
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> b = np.array([[21], [22], [23]])
>>> b
array([[21],
       [22],
       [23]])
>>> b.T
array([[21, 22, 23]])
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1차원 배열->2차원 배열 전환
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> b = np.array([21, 22, 23])
>>> b
array([21, 22, 23])
>>> np.array([b])
array([[21, 22, 23]])


정리

1. 2차원 배열에 붙일때는 2차원 배열로 변환해서 붙인다.

2. 붙일려고 하는 크기가 다를때는 오류 발생

3. 가로 세로 전환시에는 np.T 전치 행렬 이용

4. 하나만 제대로 외우자 np.hstack([]), np.vstack([])




댓글 없음:

댓글 쓰기