상위 목록: 하위 목록: 작성 날짜: 읽는 데 4 분 소요

이어 붙이기(Append)

import numpy as np

arr = np.array([
    [
        [1, 1],
        [2, 2]
    ],
    [
        [3, 3],
        [4, 4]
    ]
])


item = np.array([
    [5, 5],
    [6, 6]
])

print(arr.shape)
print(item.shape)

append = np.append(arr, item.reshape(1, 2, 2), axis=0)

print(append)
결과
(2, 2, 2)
(2, 2)
[[[1 1]
  [2 2]]

 [[3 3]
  [4 4]]

 [[5 5]
  [6 6]]]

이어 붙이기 함수(np.append)는 내장 이어 붙이기 함수(append)와 다르게, 축(axis)을 지정할 경우 두 배열의 차원 수가 같아야 붙일 수 있습니다.

또한, 연결하는 축을 제외한 나머지 축의 크기도 같아야 합니다.

만약, Numpy 배열이 아닌 List 배열이라면 내장 이어 붙이기 함수를 통해 큰 문제 없이 이어 붙일 수 있습니다.

그 이유는 List는 Container 형식의 단순 값을 저장하는 자료형이기 때문입니다.

Numpy 배열은 연산을 위한 라이브러리입니다.

arr 변수의 차원 형태는 (2, 2, 2)를 가지며, item 변수는 (2, 2)를 갖습니다.

이 값을 이어 붙일 때, (2, 2) 배열이 앞쪽 두 축(2, 2, 2)에 대응하는지, 뒤쪽 두 축(2, 2, 2)에 대응하는지 알 수 없습니다.

그러므로, item 배열의 차원 크기를 arr 배열의 차원 크기와 동일하게 구성한다음 명시적으로 어떤 축(axis)에 연결할지 설정합니다.

이어 붙이기 함수는 결과 = np.append(배열1, 배열2, 축)을 통해 배열을 이어 붙일 수 있습니다.

위의 예제는 item을 (1, 2, 2)로 변경해 첫 번째 축(axis=0)에 연결하는 예시입니다. 결과의 형태는 (3, 2, 2)가 됩니다.

만약, 마지막 축에 연결한다면, 차원 형태를 (2, 2, 1)로 설정하고 마지막 축(axis=-1)에 연결해 사용할 수 있습니다. 결과의 형태는 (2, 2, 3)이 됩니다.


# 위 예제의 arr, item 변수를 그대로 사용합니다.
append = np.append(arr, item.reshape(2, 2, 1), axis=-1)

print(append)
결과
[[[1 1 5]
  [2 2 5]]

 [[3 3 6]
  [4 4 6]]]

np.append는 원본 배열을 변경하지 않고 항상 새로운 배열을 반환합니다. 그러므로 반환값을 변수에 다시 할당해야 합니다.



축을 지정하지 않은 이어 붙이기

import numpy as np

arr = np.array([[1, 2], [3, 4]])

print(np.append(arr, [5, 6]))
print(np.append(arr, [[5, 6]], axis=0))
결과
[1 2 3 4 5 6]
[[1 2]
 [3 4]
 [5 6]]

축(axis)을 입력하지 않는 경우, np.append는 두 배열을 모두 1차원으로 평탄화한 다음 이어 붙입니다.

그러므로 2차원 배열에 값을 추가하더라도 결과는 1차원 배열이 됩니다.

배열의 형태를 유지하려면 축(axis)을 명시하고, 추가할 배열도 [[5, 6]]처럼 같은 차원 수로 구성해야 합니다.



빈 배열에서 이어 붙이기

import numpy as np

arr = np.empty((1, 2), dtype=int)

for i in range(5):
    item = np.array([[i, i]])
    arr = np.append(arr, item, axis=0) 

arr = np.delete(arr, [0, 0], axis=0)
print(arr)
결과
[[0 0]
 [1 1]
 [2 2]
 [3 3]
 [4 4]]

List 자료형에서는 L = []로 선언 후 내장 이어 붙이기 함수(append)를 활용해 자유롭게 배열의 형태를 생성하곤 했습니다.

하지만, Numpy 배열에서는 앞서 설명한 이유처럼 어떤 형태로 이어 붙이기를 실행할지 알 수 없습니다.

그러므로, 이어 붙일 배열의 형태를 미리 선언(np.empty)합니다.

반복문을 통해 이어 붙이기가 완료되면, 첫 번째 행에 있는 더미 값을 제거해야 합니다.

제거 함수(np.delete)를 통해 특정 요소값을 삭제합니다.

결과 = np.delete(배열, 색인, 축)을 통해 배열의 요소를 제거할 수 있습니다.

제거 함수는 색인과 축 값에 따라 제거할 대상을 설정합니다.

색인은 범위가 아닌 제거할 위치의 목록입니다. 정수 하나, 목록, slice 객체 등을 입력할 수 있습니다.

예시에서는 첫 번째 축(axis=0)을 대상으로 [0, 0]을 입력했으며, 중복된 색인은 한 번만 적용되므로 첫 번째 행만 제거됩니다. np.delete(arr, 0, axis=0)과 같은 결과입니다.

즉, 더미 값인 np.empty 값이 제거되고 이어 붙인 값만 남게됩니다.

  • Tip : np.empty는 메모리를 초기화하지 않으므로 더미 행에는 임의의 값이 들어 있습니다. 반드시 제거한 다음 사용해야 합니다.



크기가 0인 배열에서 이어 붙이기

import numpy as np

arr = np.empty((0, 2), dtype=int)

for i in range(5):
    item = np.array([[i, i]])
    arr = np.append(arr, item, axis=0)

print(arr.shape)
print(arr)
결과
(5, 2)
[[0 0]
 [1 1]
 [2 2]
 [3 3]
 [4 4]]

np.empty((0, 2))처럼 첫 번째 축의 크기가 0인 배열을 선언하면, 열의 개수는 2로 정해져 있지만 행은 하나도 없는 배열이 생성됩니다.

이 배열에 이어 붙이면 더미 값이 생기지 않으므로, np.delete로 첫 번째 행을 제거하는 과정이 필요하지 않습니다.



목록으로 모은 다음 변환하기

import numpy as np

items = []

for i in range(5):
    items.append([i, i])

arr = np.array(items)
print(arr)
결과
[[0 0]
 [1 1]
 [2 2]
 [3 3]
 [4 4]]

np.append는 호출할 때마다 배열 전체를 새로운 메모리에 복사합니다.

그러므로 반복문 안에서 np.append를 여러 번 호출하면, 요소의 개수가 늘어날수록 복사량이 계속 커져 속도가 크게 느려집니다.

반복문으로 값을 모으는 경우에는 List의 내장 이어 붙이기 함수(append)로 값을 모은 다음, 마지막에 한 번만 np.array로 변환하는 것이 효율적입니다.

여러 개의 Numpy 배열을 모았다면 np.concatenate(목록, axis)나 np.stack(목록, axis)으로 한 번에 연결할 수 있습니다.

  • Tip : 최종 크기를 미리 알고 있다면 np.zeros((5, 2))처럼 배열을 먼저 할당한 다음 arr[i] = [i, i]로 값을 채우는 방법이 가장 빠릅니다.



삽입(Insert)

import numpy as np

arr = np.array([[1, 1], [2, 2], [3, 3]])

print(np.insert(arr, 1, [9, 9], axis=0))
print(np.insert(arr, 1, 0, axis=1))
print(np.delete(arr, [0, 2], axis=0))
결과
[[1 1]
 [9 9]
 [2 2]
 [3 3]]
[[1 0 1]
 [2 0 2]
 [3 0 3]]
[[2 2]]

삽입 함수(np.insert)는 배열의 끝이 아닌 특정 위치에 값을 추가합니다.

결과 = np.insert(배열, 색인, 값, 축)을 통해 색인 위치의 앞에 값을 삽입합니다.

첫 번째 예시는 첫 번째 축(axis=0)의 1번 색인 앞에 [9, 9] 행을 삽입합니다.

두 번째 예시는 두 번째 축(axis=1)의 1번 색인 앞에 0을 삽입합니다. 스칼라 값은 브로드캐스팅되어 모든 행에 적용됩니다.

세 번째 예시처럼 np.delete에 여러 색인을 목록으로 입력하면, 해당 위치의 요소를 한 번에 제거합니다.

np.insert와 np.delete도 np.append와 마찬가지로 원본을 변경하지 않고 새로운 배열을 반환합니다.

댓글 남기기