Python/NumPy | Pandas

[Python] Numpy - 배열의 생성과 변형 2

비번변경 2022. 11. 18. 20:36

개요

2022.11.11 - [Python] NumPy - 배열 1

2022.11.12 - [Python] NumPy - 배열 2 (인덱싱과 슬라이싱)

2022.11.13 - [Python] NumPy - 배열의 생성과 변형 1

에 이어 NumPy에 대해서 계속 정리한다.

 

 

배열의 크기 변형

reshape

reshape 함수로 배열 내 데이터는 유지하면서 형태를 변경할 수 있다.

a = np.arange(10)
a
a.reshape(2, 5)

# 실행 결과
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

사용하는 원소의 개수가 정해져 있기 때문에 매개변수로 전달하는 튜플 중 하나가 -1이면, 자동으로 차원을 계산하여 크기를 변경한다.

a = np.arange(10)
a = a.reshape(2, -1)

# 실행 결과
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

 

flatten / ravel

다차원 배열을 1차원으로 만들 때 사용한다.

a.flatten()
a.ravel()

# 실행 결과
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
💡
길이가 5인 1차원 배열, 5 X 1인 배열, 1 X 5인 배열 각각은 다른 배열이다.

 

np.newaxis

1차원만 증가시킨 배열을 구할 때 사용한다.

a = np.arange(5)
a.[:, np.newaxis]

# 실행 결과
array([[0],
       [1],
       [2],
       [3],
       [4]])

 

 

배열 연결

NumPy에서는 행의 수나 열의 수가 같은 두 개 이상의 배열을 연결(concatenate)하여 더 큰 배열을 만들 수 있다.

  • hstack : 행의 수가 같은 두 개 이상의 배열을 옆으로 연결하여 열의 수가 더 많은 배열을 만든다. 연결할 배열은 리스트로 전달한다.
a1 = np.ones((2, 3))
a2 = np.zeros((2, 1))

a1
a2
np.hstack([a1, a2])

# 실행 결과
array([[1., 1., 1.],
       [1., 1., 1.]])
array([[0.],
       [0.]])
array([[1., 1., 1., 0.],
       [1., 1., 1., 0.]])
  • vstack : 열의 수가 같은 두 개 이상의 배열을 세로로 연결하여 행의 수가 더 많은 배열을 만든다. 연결할 배열은 리스트로 전달한다.
a1 = np.ones((1, 3))
a2 = np.zeros((2, 3))

a1
a2
np.vstack([a1, a2])


# 실행 결과
array([[1., 1., 1.]])
array([[0., 0., 0.],
       [0., 0., 0.]])
array([[1., 1., 1.],
       [0., 0., 0.],
       [0., 0., 0.]])
  • dstack : 행/열이 아닌 깊이(depth) 방향으로 배열을 합치며 가장 안쪽 원소의 차원이 증가한다. 즉, 가장 내부의 숫자 원소가 배열이 된다. 아래의 예제의 경우, 2개의 3 X 4 배열이 1개의 3 X 4 X 2 배열이 된다.
c1 = np.ones((3, 4))
c2 = np.zeros((3, 4))

c1
c2
np.dstack([c1, c2])
(np.dstack([c1, c2])).shape


# 실행 결과
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.]])
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)
  • stack : dstack의 기능을 확장한 것으로 사용자가 지정한 축(axis)으로 배열을 연결한다. 기본값은 axis = 0으로 맨 바깥에 차원이 추가된다.
c = np.stack([c1, c2])
c
c.shape

# 실행 결과
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.]]])
(2, 3, 4)
  • r_ : hstack과 비슷하게 배열을 좌우로 연결한다. 다만 함수임에도 불구하고 대괄호를 쓰는 특수 함수이다.
np.r_[np.array([1, 2, 3]), np.array([4, 5, 6])]

# 실행 결과
array([1, 2, 3, 4, 5, 6])
  • c_ : 배열의 차원을 증가시킨 후 좌우로 연결한다. 1차원 배열은 2차원 배열이 된다.
np.c_[np.array([1, 2, 3]), np.array([4, 5, 6])]

# 실행 결과
array([[1, 4],
       [2, 5],
       [3, 6]])
  • tile : 같은 배열을 반복하여 연결한다.
a = np.array([[0, 1, 2], [3, 4, 5]])
np.tile(a, 2)

# 실행 결과
array([[0, 1, 2, 0, 1, 2],
       [3, 4, 5, 3, 4, 5]])

 

 

2차원 그리드 포인트 생성

변수가 2개인 2차원 함수의 그래프를 그리거나 표를 작성하기 위해서는 (x, y) 순서쌍을 생성하여 각 좌표에 대한 함숫값을 구해야 한다.

예로 들어 \(0 \le x \le 2\)이고 \(0 \le y \le 4 \)인 경우, 아래 순서쌍에 대한 함숫값을 계산해야 한다.

$$ (x, y) = (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1,  0), … (2, 4) $$

이러한 순서쌍을 만들 때는 가로, 세로축의 점을 나타내는 두 벡터를 인수로 받아 그 조합을 출력하는 meshgrid 함수를 사용할 수 있다.

x = np.arange(3)
y = np.arange(5)
X, Y = np.meshgrid(x, y)

# X
array([[0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2],
       [0, 1, 2]])
       
# Y
array([[0, 0, 0],
       [1, 1, 1],
       [2, 2, 2],
       [3, 3, 3],
       [4, 4, 4]])
       
[list(zip(x, y)) for x, y in zip(X, Y)]
[[(0, 0), (1, 0), (2, 0)],
 [(0, 1), (1, 1), (2, 1)],
 [(0, 2), (1, 2), (2, 2)],
 [(0, 3), (1, 3), (2, 3)],
 [(0, 4), (1, 4), (2, 4)]]

 

 

참고 문서

데이터 사이언스 스쿨 - 3.2 배열의 생성과 변형