팁뚠이 입니다. 많은 분들이 알고 계시지만 파이썬은 인터프리터(interpreter) 언어로 대화형 방식입니다. 이러다 보니 C언어나 자바에 비해 속도가 많이 느립니다. 실제로도 필드에선 파이썬은 데이터 분석, 알고리즘 개발용으로 사용하고 iot 나 H/W에 담을 때는 C언어나 자바로 변환하여 사용합니다. 물론 클라우드를 사용한다면 도커를 활용하여, 이 부분이 해소가 됩니다만 모든 곳에 클라우드가 들어갈 순 없기 때문에, 파이썬을 사용하려면 속도를 고려하지 않을 수 없습니다. 그러나, C언어나 자바의 경우 상대적으로 익히기 어려운 언어이고, AI나 특정 필드에 있어선 파이썬만큼 라이브러리가 잘 구축되어 있지 않습니다. 결국엔 파이썬을 써야 하는 인구는 계속 늘고 있는 상황에서 파이썬을 활용해 최대한 속도를 내는 게 관건인 것입니다. 그러면 파이썬을 사용할 때 빠르게 하려면 어떻게 해야 할지?
Numpy, pandas 등 C로 컴파일된 라이브러리를 최대한 활용
Numpy, pandas 등은 C로 컴파일된 라이브러리이다 보니, 메모리를 RAM처럼 비가역적으로 활용해 속도가 훨씬 빠릅니다. 자세한 설명을 다루려면 길어지기 때문에, Numpy, pandas 등의 array나 dataframe을 활용하고, 내부 함수를 이용하는 게 기존 python list를 사용하는 것보다 빠릅니다. (세부적으로 계산하면 python list로 데이터를 조합 후 dataframe으로 변환하는 게 더 빠릅니다만 일반적인 내용에선 numpy, pandas 등이 빠릅니다. ) 특히 numpy의 ndarray로 타입을 변환 후에 numpy의 함수들을 활용하면 굉장히 속도가 빠르게 올라옵니다. 그중에서도 특히 비교가 될 만한 내용이 브로드캐스팅(broadcasting)인데, 브로드 캐스팅은 ai 머신러닝/딥러닝 등에 많이 사용하는 기능이니 꼭 익혀두시면 활용처가 많습니다. 우선 브로드캐스팅의 정의부터 알아보면 아래와 같습니다.
브로드캐스팅: 서로 다른 모양의 array들 간 연산이 되도록 자동으로 형태가 바뀐 뒤 연산
가령 예를 들면, (3x1) 어레이와 (1x3) 어레이끼리 더하려고 하면, 덧셈이 되지 않습니다. 고등학교 때 행렬 간 연산 시, 덧셈, 뺄셈에 대해서는 같은 크기여야만 가능하기 때문입니다. 근데, 브로드캐스팅을 활용하면 (3x1) 어레이를 (3x3)으로 변환하고, (1x3) 어레이를 (3x3) 어레이로 바꾸어 자동으로 계산을 해줍니다. 결과치도 역시 (3x3) 어레이로 되는 방식입니다. 그럼 이런 질문을 하실 겁니다. 이런 걸 왜 사용하냐? 어떤 경우에 사용하느냐? 그냥 어레이를 바꾸면 되지 않느냐? 하고 물으실 텐데, 그에 해당하는 예시를 하나 들어보겠습니다.
2차원 100개의 점 사이의 거리를 파이썬으로 계산하라
이 경우, 일반적은 생각은 List로 (100, 2)의 점을 생성하고, for문을 돌려서, 100개 간의 두 점 사이를 피타고라스 법칙으로 계산하게 됩니다. 이 경우 for 문을 중첩해야 하고 계산량이 어마어마해져서 시간이 많이 걸립니다. 그에 반해 매트릭스 형태로, (100x2) 매트릭스 두 개 간 계산을 바로 하게 된다면 계산 자체가 간소화됩니다. 이때 브로드 캐스팅을 쓰면 매트릭스 간 계산은 더욱 빠르게 됩니다. 본 포스팅의 핵심은 아래와 같습니다.
python은 브로드캐스팅을 활용한 매트릭스 연산이 가장 빠르다.
결국 많은 계산을 우선 매트릭스 연산을 할 수 있게 변환 후, 브로드캐스팅을 활용하자는 데 있습니다. 코드를 예시로 비교해 보겠습니다. (100x1), (1x100) 매트릭스를 임의로 생성 후, 두 개를 서로 더 했을 때, 브로드캐스팅을 활용한 연산과 파이썬 for-loop과의 속도를 비교해보겠습니다.
import numpy as np
test1 = np.random.randint(0, 10, 100)
test2 = np.random.randint(0, 10, 100)
result = np.empty((100, 100))
#브로드캐스팅
result = test1.reshape(100, 1) + test2.reshape(1, 100)
#for-loop
for i in range(100):
for j in range(100):
result[i,j] = test1[i] + test2[j]
브로드 캐스팅과 for문을 활용해 계산한 결과에 대해 각각 시간을 비교해보시면 매우 큰 차이가 납니다. 코드 자체도 한 줄로 간소화되는 데, for문을 중첩해서 활용하지 않고, numpy의 브로드캐스팅 기능을 활용해 굉장히 빠른 속도가 나옵니다. 한 번 직접 코드를 돌려보시고 확인해보시기 바랍니다. 보다 큰 차이 비교를 위해서는 큰 매트릭스 사이즈로 실행 시 더 많이 납니다. 그런데, 모든 연산이 전부 for-loop을 사용하지 않고, 매트릭스 연산만으론 하진 못하고, for-loop이 주는 직관적인 내용(C언어부터 for문을 사용해, 익숙함)이 있다 보니 필요한 경우엔 for문을 활용하되, 가능하면 매트릭스 연산이 빠르다가 답입니다. 결론으로 정리하면 아래와 같습니다.
- List 간 연산보다는 매트릭스 간 연산으로 변환
- 매트릭스 간 연산은 브로드 캐스팅을 활용하면 속도가 비약적으로 빨라짐
'파이썬팁' 카테고리의 다른 글
통계 부트스트랩(Bootstrap) 개념 파이썬을 이용해 알아보기 (0) | 2022.04.18 |
---|---|
통계 중심극한정리 개념 파이썬 코드로 이해하기 (0) | 2022.04.17 |
파이썬 클래스 상속 개념 잡기 (0) | 2022.04.08 |
파이썬 _과 __은 무슨 의미를 가질까요? public, private 속성 (0) | 2022.04.03 |
*args와 **kwargs는 파이썬에서 무엇일까? (0) | 2022.04.01 |