본문 바로가기
프로그래밍/Python 관련 정보

[Python 기초] Broadcasting

by 물박사의 저장공간 2025. 2. 22.

2025.02.24 - [프로그래밍/Python 관련 정보] - [Pandas] Table of Contents


Boradcasting 에 대해서는 다들 많이 아실텐데 좀 정확하게 정리를 한 번 해보겠습니다. 

Rule1. 총 차원의 개수가 맞지 않는 경우 차원을 확장시켜줍니다. 이 때, 앞에 있는 차원을 열어주고 그 차원의 크기는 1로 만들어줍니다. 

Rule2. 총 차원의 개수는 동일하지만 개별 차원의 크기가 동일하지 않을 때 차원의 크기를 늘려줄 수 있습니다. 단, 연산에 참여하는 배열의 차원의 크기가 1이어야 합니다. 

 

말로는 쉽게 요약해보려고 해도 어렵네요.. 예시를 보면서 이해해봅시다. 

예시 1: (3, 1) + (3,) → (3, 3)

import numpy as np

# (3, 1) 형태의 배열 생성
a = np.array([[1], [2], [3]])

# (3,) 형태의 배열 생성
b = np.array([10, 20, 30])

print("Step 1: 초기 배열")
print("a shape:", a.shape)
print("a:\n", a)
print("b shape:", b.shape)
print("b:", b)

print("\nStep 2: b를 (1, 3) 형태로 확장 (내부적으로 수행됨)")
b_reshaped = b.reshape(1, 3)
print("b_reshaped shape:", b_reshaped.shape)
print("b_reshaped:\n", b_reshaped)

print("\nStep 3: a와 b_reshaped를 (3, 3) 형태로 확장 (내부적으로 수행됨)")
a_broadcasted = np.broadcast_to(a, (3, 3))
b_broadcasted = np.broadcast_to(b_reshaped, (3, 3))
print("a_broadcasted:\n", a_broadcasted)
print("b_broadcasted:\n", b_broadcasted)

print("\nStep 4: 최종 결과")
result = a + b
print("result shape:", result.shape)
print("result:\n", result)
Step 1: 초기 배열
a shape: (3, 1)
a:
 [[1]
 [2]
 [3]]
b shape: (3,)
b: [10 20 30]

Step 2: b를 (1, 3) 형태로 확장 (내부적으로 수행됨)
b_reshaped shape: (1, 3)
b_reshaped:
 [[10 20 30]]

Step 3: a와 b_reshaped를 (3, 3) 형태로 확장 (내부적으로 수행됨)
a_broadcasted:
 [[1 1 1]
 [2 2 2]
 [3 3 3]]
b_broadcasted:
 [[10 20 30]
 [10 20 30]
 [10 20 30]]

Step 4: 최종 결과
result shape: (3, 3)
result:
 [[11 21 31]
 [12 22 32]
 [13 23 33]]

 

(3,) 가 (3, 1)로 확장되는 것이 아니라 (1, 3)으로 확장된다는 점 기억해주세요.

 

 

예시2)  (2, 3, 5) + (3, 5) → (2, 3, 5)

import numpy as np

# (2, 3, 5) 형태의 배열 생성
a = np.arange(30).reshape(2, 3, 5)

# (3, 5) 형태의 배열 생성
b = np.arange(15).reshape(3, 5)

print("Step 1: 초기 배열")
print("a shape:", a.shape)
print("a:\n", a)
print("\nb shape:", b.shape)
print("b:\n", b)

print("\nStep 2: b를 (1, 3, 5) 형태로 확장 (내부적으로 수행됨)")
b_reshaped = b.reshape(1, 3, 5)
print("b_reshaped shape:", b_reshaped.shape)
print("b_reshaped:\n", b_reshaped)

print("\nStep 3: b_reshaped를 (2, 3, 5) 형태로 확장 (내부적으로 수행됨)")
b_broadcasted = np.broadcast_to(b_reshaped, (2, 3, 5))
print("b_broadcasted shape:", b_broadcasted.shape)
print("b_broadcasted:\n", b_broadcasted)

print("\nStep 4: 최종 결과")
result = a + b
print("result shape:", result.shape)
print("result:\n", result)
Step 1: 초기 배열
a shape: (2, 3, 5)
a:
 [[[ 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 27 28 29]]]

b shape: (3, 5)
b:
 [[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]]

Step 2: b를 (1, 3, 5) 형태로 확장 (내부적으로 수행됨)
b_reshaped shape: (1, 3, 5)
b_reshaped:
 [[[ 0  1  2  3  4]
   [ 5  6  7  8  9]
   [10 11 12 13 14]]]

Step 3: b_reshaped를 (2, 3, 5) 형태로 확장 (내부적으로 수행됨)
b_broadcasted shape: (2, 3, 5)
b_broadcasted:
 [[[ 0  1  2  3  4]
   [ 5  6  7  8  9]
   [10 11 12 13 14]]

  [[ 0  1  2  3  4]
   [ 5  6  7  8  9]
   [10 11 12 13 14]]]

Step 4: 최종 결과
result shape: (2, 3, 5)
result:
 [[[ 0  2  4  6  8]
  [10 12 14 16 18]
  [20 22 24 26 28]]

 [[15 17 19 21 23]
  [25 27 29 31 33]
  [35 37 39 41 43]]]

 

 

예시3) (4, 4) + (3,) : operands could not be broadcast together with shapes (4,4) (3,)

총 차원의 개수를 맞춰 준 뒤에 무조건 broadcasting이 가능한 것이 아니라 한 배열의 차원크기가 1이어야 한다고 했습니다. 이 예시에서는 불가능하므로 Value error가 발생합니다.

import numpy as np

a = np.ones((4, 4))
b = np.array([1, 2, 3])

try:
    result = a + b
except ValueError as e:
    print("ValueError 발생:", e)