NumPy에서 산술 연산은 기본적으로 배열의 크기가 같거나 호환 가능한 경우에만 수행됩니다. 하지만 브로드캐스팅(Broadcasting)을 활용하면 크기가 다른 배열 간에도 산술 연산을 적용할 수 있습니다. 브로드캐스팅이란 더 작은 차원(ndim)을 가진 배열의 형태(shape) 앞에 '1'을 추가하고, 이를 필요한 형태로 확장하여 연산이 가능하도록 만드는 메커니즘입니다. 즉, 실제로 데이터를 복사하지 않으면서도 배열의 형태를 유연하게 변형해 연산을 수행하는 효율적인 방식입니다.
배열 브로드캐스팅의 규칙
차원(ndim)이 더 작은 배열의 형태 앞에 '1'이 추가(선행)됩니다.
출력 형태의 각 차원 크기는 입력 배열들 중 해당 차원의 최대 크기로 결정됩니다.
입력 배열은 특정 차원의 크기가 출력 크기와 일치하거나 정확히 1일 때만 계산에 사용할 수 있습니다.
입력 배열의 특정 차원 크기가 1이라면, 해당 차원의 첫 번째 데이터 항목이 그 차원을 따르는 모든 계산에 재사용됩니다.
예제 코드
아래 예제는 NumPy 배열을 사용한 연산 과정에서 브로드캐스팅이 어떻게 적용되는지 보여줍니다.
import numpy as np
a = np.array([[0.0, 0.0, 0.0],
[10.0, 10.0, 10.0],
[20.0, 20.0, 20.0],
[30.0, 30.0, 30.0]])
b = np.array([1.0, 2.0, 3.0])
print('첫 번째 배열:')
print(a)
print('\n')
print('두 번째 배열:')
print(b)
print('\n')
print('첫 번째 배열 + 두 번째 배열')
print(a + b)실행 결과
위 코드를 실행하면 다음과 같은 결과가 출력됩니다.
첫 번째 배열:
[
[ 0. 0. 0.]
[ 10. 10. 10.]
[ 20. 20. 20.]
[ 30. 30. 30.]
]
두 번째 배열:
[ 1. 2. 3.]
첫 번째 배열 + 두 번째 배열
[
[ 1. 2. 3.]
[ 11. 12. 13.]
[ 21. 22. 23.]
[ 31. 32. 33.]
]브로드캐스팅 동작 원리
위 예제에서 배열 a는 형태가 (4, 3)인 2차원 배열이고, 배열 b는 형태가 (3,)인 1차원 배열입니다. NumPy는 먼저 b의 형태 앞에 '1'을 추가해 (1, 3)으로 만든 뒤, 이를 (4, 3)으로 확장합니다. 결과적으로 각 행마다 [1.0, 2.0, 3.0]이 더해진 것과 같은 효과를 얻습니다.
중요한 점은 이 과정에서 실제 데이터 복사가 발생하지 않는다는 것입니다. NumPy는 내부적으로 반복 연산을 처리하므로 메모리를 절약하면서도 대규모 배열 연산을 빠르게 수행할 수 있습니다. 이러한 브로드캐스팅은 벡터화 연산의 핵심 요소로, 파이썬 반복문 없이 간결하고 효율적인 코드를 작성하는 데 큰 도움이 됩니다.