[ Numpy ] 배열 복사, 붙여넣기 함수! (np.repeat, np.tile)
[ Python 3 ] Numpy 란 무엇인가? (ndarray 클래스)
배열을 복사, 또는 반복해서 나타내 주는 함수에 대해 알아보자!
목차
- np.repeat
- np.tile
- 그림 예시를 통해 쉽게 이해해 보자(꼭 확인해 보세요!!!)
np.repeat(a, repeats, axis=None)
배열의 요소를 반복하는 함수입니다.
배열의 각 요소 바로 뒤에 동일한 값을 추가한다는 점이 특징이다!
- a : 복사하고 싶은 배열
- repeats : int 또는 array of ints. 각 요소를 얼마나 반복하는지를 결정
- axis : int, 어떤 방향으로 복사해서 붙여 넣을 건지 결정
[주의할점]
axis 에 따라서 input array a 의 shape 을 고려한다.
axis = None 일 경우, shape 에 상관없이 각 요소를 바로 뒤에 추가.
axis = 0 일 경우, 가장 바깥쪽 괄호를 기준으로 각 요소를 추가.
→ 이때, array 자체를 하나의 요소로 생각한다.
axis = 1 일 경우, 그 다음 바깥쪽 괄호를 기준으로 각 요소를 추가한다.
...
[쉽게 이해하기]
axis에 관해 잘 이해가 되지 않는다면 output shape 을 생각해보면 쉽다!!!!!!
>>> import numpy as np
# 숫자 2를 7번 반복한 배열 반환!
>>> np.repeat(2,7)
array([2, 2, 2, 2, 2, 2, 2])
np.repeat(2,7).shape
(7,)
# 2 x 2 array x를 각 axis에 대해 repeat 예시
>>> x = np.array([[1,2],[3,4]])
>>> x
array([[1, 2],
[3, 4]])
>>> x.shape
(2, 2)
# 1. axis = None 일 경우
# : shape에 상관없이 flatten 해서 처리
>>> np.repeat(x,3)
array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])
>>> np.repeat(x,3).shape
(12,)
# 2. axis = 0 일경우
# : 가장 바깥쪽 괄호를 기준으로 생각
>>> np.repeat(x,3,axis=0)
array([[1, 2],
[1, 2],
[1, 2],
[3, 4],
[3, 4],
[3, 4]])
>>> np.repeat(x,3,axis=0).shape
(6, 2)
# 3. axis = 1 일경우
# : 다음 바깥쪽 괄호를 기준으로 생각
>>> np.repeat(x,3,axis=1)
array([[1, 1, 1, 2, 2, 2],
[3, 3, 3, 4, 4, 4]])
>>> np.repeat(x,3,axis=1).shape
(2, 6)
output shape 을 보면 늘리고자 하는 axis 에 대해서 늘어난 것을 알 수 있다!!
만약 3차원 배열이라면??
input array 의 차원이 늘어나더라도 동일한 개념으로 이해할 수 있다.
>>> import numpy as np
>>> x = np.arange(27).reshape((3,3,3)) # 3x3x3 input array
>>> x
array([[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]],
[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]],
[[18, 19, 20],
[21, 22, 23],
[24, 25, 26]]])
>>> np.repeat(x,2)
array([ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25,
25, 26, 26])
>>> np.repeat(x,2,axis=0)
array([[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]],
[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]],
[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]],
[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]],
[[18, 19, 20],
[21, 22, 23],
[24, 25, 26]],
[[18, 19, 20],
[21, 22, 23],
[24, 25, 26]]])
>>> np.repeat(x,2,axis=0).shape
(6, 3, 3)
>>> np.repeat(x,2,axis=1)
array([[[ 0, 1, 2],
[ 0, 1, 2],
[ 3, 4, 5],
[ 3, 4, 5],
[ 6, 7, 8],
[ 6, 7, 8]],
[[ 9, 10, 11],
[ 9, 10, 11],
[12, 13, 14],
[12, 13, 14],
[15, 16, 17],
[15, 16, 17]],
[[18, 19, 20],
[18, 19, 20],
[21, 22, 23],
[21, 22, 23],
[24, 25, 26],
[24, 25, 26]]])
>>> np.repeat(x,2,axis=1).shape
(3, 6, 3)
>>> np.repeat(x,2,axis=2)
array([[[ 0, 0, 1, 1, 2, 2],
[ 3, 3, 4, 4, 5, 5],
[ 6, 6, 7, 7, 8, 8]],
[[ 9, 9, 10, 10, 11, 11],
[12, 12, 13, 13, 14, 14],
[15, 15, 16, 16, 17, 17]],
[[18, 18, 19, 19, 20, 20],
[21, 21, 22, 22, 23, 23],
[24, 24, 25, 25, 26, 26]]])
>>> np.repeat(x,2,axis=2).shape
(3, 3, 6)
np.tile(A, reps)
np.tile 또한 유사하게 동일한 배열을 반복해서 복사 붙여넣기 하는 함수이다.
- A : Input array
- reps : 각 axis에 대해 어떻게 반복할 건지 결정한다. 복잡하니 예시를 통해 보는게 빠르다.
Input(1D Array )일때
>>> import numpy as np
>>> a = np.array([0,1,2])
>>> a
array([0, 1, 2])
>>> a.shape
(3,)
>>> np.tile(a,2)
array([0, 1, 2, 0, 1, 2])
>>> np.tile(a,2).shape
(6,)
>>> np.tile(a,(2,3))
array([[0, 1, 2, 0, 1, 2, 0, 1, 2],
[0, 1, 2, 0, 1, 2, 0, 1, 2]])
>>> np.tile(a,(2,3)).shape
(2, 9)
>>> np.tile(a,(2,3,4))
array([[[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]],
[[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2],
[0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]]])
>>> np.tile(a,(2,3,4)).shape
(2, 3, 12)
Input(2D Array)일때
>>> import numpy as np
>>> a = np.array([[1,2],[3,4]])
>>> a
array([[1, 2],
[3, 4]])
>>> a.shape
(2, 2)
>>> np.tile(a,2)
array([[1, 2, 1, 2],
[3, 4, 3, 4]])
>>> np.tile(a,2).shape
(2, 4)
>>> np.tile(a,(2,3))
array([[1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4],
[1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4]])
>>> np.tile(a,(2,3)).shape
(4, 6)
>>> np.tile(a,(2,3,4))
array([[[1, 2, 1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4, 3, 4],
[1, 2, 1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4, 3, 4],
[1, 2, 1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4, 3, 4]],
[[1, 2, 1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4, 3, 4],
[1, 2, 1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4, 3, 4],
[1, 2, 1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4, 3, 4]]])
>>> np.tile(a,(2,3,4)).shape
(2, 6, 8)
그런데 np.repeat 함수와 np.tile 함수의 차이는 무엇일까??
바로 복사하는 방법 차이이다.
np.repeat 의 경우, 내용은 유지한채로 배열 자체의 사이즈를 키우는 느낌이고,
np.tile 의 경우, 동일한 내용의 형태를 반복해서 붙여주는 느낌이다.
다시정리하면,
용어에서도 알 수 있듯이 input array를 하나의 욕실 타일(블록)처럼 생각하고
형태를 유지한 채로 가로로 붙일지 세로로 붙일지 고민하는게 np.tile 이다.
[그림 예시를 통해 쉽게 이해해 보자]
import numpy as np
import matplotlib.pyplot as plt
i = plt.imread('ex.jpeg')
plt.imshow(i)
np.repeat
i_repeat = np.repeat(i,2,axis=0)
plt.imshow(i_repeat)
# 세로로 2배 길어짐
i_repeat = np.repeat(i,2,axis=1)
plt.imshow(i_repeat)
# 가로로 두배 길어짐
np.tile
i_tile = np.tile(i,(1,2,1))
plt.imshow(i_tile)
# 입력 그림 타일이 가로로 하나 더 추가 됨.
i_tile = np.tile(i,(2,1,1))
plt.imshow(i_tile)
# 입력 그림 타일이 세로로 하나 더 추가됨
i_tile = np.tile(i,(2,2,1))
plt.imshow(i_tile)
# 가로 세로 하나씩 더 추가 됨.