본문 바로가기
Python

[Python] Numpy Broadcasting 개념

by 하응 2022. 2. 24.

Numpy 라이브러리에서 브로드캐스팅(Broadcasting)이란: 

 

산술 연산 대상이 되는 배열(array)들의 모양(shape)이 다른 경우에도, 연산이 가능하도록 배열들의 모양을 처리하는 방법을 의미한다.

 

더 작은 배열이 큰 배열의 모양에 맞춰지는 방식으로 작동하고, 벡터화를 가능하도록 하여, loop가 python이 아닌 C에서 수행되도록 한다. 

 

브로드캐스팅을 활용하면, 불필요한 사본을 생성하지 않아도 되기 때문에 효율적인 코드를 작성할 수 있다.

* 종종 큰 배열에 대한 브로드캐스팅 연산으로 메모리를 비효율적으로 사용하거나, 차원이 커져서 코드 해석이 어려운 경우에는 outer loop를 사용하는 것이 더 좋다.  


Numpy 공식 문서에서 아래와 같이 해당 개념에 대한 설명을 제공하고 있다. 

Numpy 라이브러리 공식 문서 웹사이트


브로드캐스팅(Broadcasting) 예시:

 

다음 표는 식자재 항목당 칼로리 정보를 나타내고 있다.

식자재 100g당 탄수화물, 단백질, 지방의 칼로리 정보

만일 '계란'의 탄수화물 비율을 알고 싶다면 탄수화물 칼로리를 탄수화물, 단백질, 지방 칼로리를 모두 더한 값으로 나눠주면 된다. 4.4/(4.4+52.0+99.0), 대략 0.03%로 계산된다. 

아래처럼 계산하면 모든 식자재에 대한 영양성분 비율을 알 수 있다.

import numpy as np
food_info = np.array([[56.0, 0.0, 4.4, 68.0],
                      [1.2, 104.0, 52.0, 8.0],
                      [1.8, 135.0, 99.0, 0.9]])
#세로 합 
sum_cal = food_info.sum(axis=0)

#3X4 배열을 1X4배열로 나눠줌
#sum_cal은 이미 1X4 모양이지만,확인을 위해 reshape()호출 
percentage = 100*food_info/sum_cal.reshape(1,4)

우선, 각 식자재에 대한 칼로리 합을 더한 (1,4)배열을 생성하고 이 배열을 sum_cal 변수에 넣어준다. 

그리고 food_info의 각 칼로리를 sum_cal 로 나눠준다. 

 

food_info의 shape은 (3,4)이고, sum_cal은 (1,4)이기 때문에 원래는 연산이 안되지만, numpy의 브로드캐스팅을 통해, sum_cal 매트릭스를 (3,4)로 바꿔준 후 연산하는 것이다. 

#기존 (1X4) sum_cal
sum_cal = [59, 239, 155.4, 76.9]

#브로드캐스팅을 거친 후 (3X4) sum_cal
sum_cal = [[59, 239, 155.4, 76.9],
            [59, 239, 155.4, 76.9],
            [59, 239, 155.4, 76.9]]

numpy 문서에도 다음처럼 이해하기 쉬운 예시가 제공되고 있다. 

*그림에서 stretching이라고 표현되는 개념이 실제로 값을 복사해서 연산하는 것은 아니라고 적혀있다. 

배열과 배열끼리의 연산에서만 브로드캐스팅이 되는 것은 아니며, 배열과 실수 관계에서도 수행된다. 

 


참고자료

반응형

댓글