안녕하십니까. 오랜만에 글을 올립니다.
1. intro
python에서 자주 사용되는 문법중 하나는 단언코 loop문일 것 입니다. 그런데 최근 이 loop문보다 효율적인 방법이 있다고 하여 정리해서 올려보자 합니다.
loop문은 수많은 반복 (때에 따라서 수십만이상)을 할때 주로 사용할 수 있습니다. 그런데 loop문의 단점은 몇 시간동안 모든 반복을 마치고나서 결과가 잘못되었구나를 알아차리는 경우가 있습니다.
그렇기 때문에 loop를 일부 대체할 수 있는 Vectorization(백터화)의 소개는 중요하다고 생각이 듭니다.
2.백터화란?
dataset에서 numpy에서 사용되는 array operation을 구현하는 기술입니다. for문보다는 모든 요소에 한번에 적용을 시킬 수가 있습니다.
2-1. 예시 1 총합.
for loop이용
import time
start = time.time()
total = 0
for item in range(0, 1500000):
total = total + item
print('sum is:' + str(total))
end = time.time()
print(end - start)
## output
sum is:1124999250000
0.13363862037658691
Vectorization이용
import numpy as np
start = time.time()
print(np.sum(np.arange(1500000)))
end = time.time()
print(end - start)
## output
1124999250000
0.005941629409790039
총합을 더하는데에도 더 빠른것을 확인할 수 있습니다. 속도차이도 17~25배정도 차이가 나는것을 확인하였습니다. (컴퓨터의 성능에 따라 다른듯합니다.)
2-2. 예시 2 사칙연산
이번에는 Pandas이용해서 DataFrame을 이용해서 분석해보겠습니다.
기본 DataFrame을 제작
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(0, 50, size=(5000000, 4)), columns=('a','b','c','d'))
df.shape
# (5000000, 4)
df.head()
loop 이용
import time
start = time.time()
# Iterating through DataFrame using iterrows
for idx, row in df.iterrows():
# creating a new column
df.at[idx,'ratio'] = 100 * (row["d"] / row["c"])
end = time.time()
print(end - start)
### output
276.2010715007782
Vectorization 이용
start = time.time()
df["ratio"] = 100 * (df["d"] / df["c"])
end = time.time()
print(end - start)
### output
0.0715641975402832
컴퓨터 성능에 따라 다르겠지만, 차이가 정말 많이 나는 것을 확인하였습니다.
2-3. 예시 3 If-else 상태문
마찬가지로 DataFrame에서 if-else를 이용하였을 때의 속도도 확인해보았습니다. 당연히 if, else 두개의 상태가 들어가기 때문에 일반적인 for loop보다 느릴것으로 예상하였습니다.
if-else포함 loop문
import time
start = time.time()
for idx, row in df.iterrows():
if row.a == 0:
df.at[idx,'e'] = row.d
elif (row.a <= 25) & (row.a > 0):
df.at[idx,'e'] = (row.b)-(row.c)
else:
df.at[idx,'e'] = row.b + row.c
end = time.time()
print(end - start)
## output
386.18501114845276
실제로 많이 느린것을 확인하실 수 있습니다. 그런데 vectorization으로 분석하면?!
start = time.time()
df['e'] = df['b'] + df['c']
df.loc[df['a'] <= 25, 'e'] = df['b'] -df['c']
df.loc[df['a']==0, 'e'] = df['d']
end = time.time()
print(end - start)
##output
0.27338457107543945
끝.. 엄청 빠릅니다.
2-4. Machine learning/ Deep learning 관련
Machine learning을 위해서는 복잡한 방정식을 풀어야합니다(Deep learning도 마찬가지입니다.)
행렬곱을 loop문으로 진행할때는 다음과 같습니다.
# dataset제작
import numpy as np
m = np.random.rand(1,5)
x = np.random.rand(5000000,5)
## 계산 loop문
zer=[]
total = 0
tic = time.process_time()
for i in range(0,5000000):
total = 0
for j in range(0,5):
total = total + x[i][j]*m[0][j]
zer.append(total )
toc = time.process_time()
print ("Computation time = " + str((toc - tic)) + "seconds")
## output
Computation time = 14.163272798000094seconds
Vectorization으로 진행하면 다음과 같습니다.
tic = time.process_time()
np.dot(x,m.T)
toc = time.process_time()
print ("Computation time = " + str((toc - tic)) + "seconds")
# output
Computation time = 0.4864272319999827seconds
정말 빠르게 결과가 나오는 것 같습니다.
3. 결론
python에서 vectorization은 큰 데이터를 다룰때 loop보다 효율적이라고 볼 수 있습니다. 다양하게 다루다 보면 loop보다 더 편하게 사용이 가능할 것입니다.
'기본적인프로그래밍 > python' 카테고리의 다른 글
[scikit-learn, python] machine learning 에 주로 사용되는 python module (1) | 2024.04.04 |
---|---|
[python] 데이터 사이언스에서 필요한 Library들? (0) | 2024.01.02 |
[pytorch,smp] 모델 weights 경로 (0) | 2023.03.14 |
[python, pandas] Data scientist라면 알아야 할 기본 기능 (0) | 2023.02.15 |
[jupyterlab] 404 Get 에러 발생 대처 (0) | 2023.02.02 |
댓글