본문 바로가기
기본적인프로그래밍/python

[python] loop문 말고 대세는? Vectorization?!

by 인포메틱스 2024. 1. 2.
반응형

안녕하십니까. 오랜만에 글을 올립니다. 

 

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보다 더 편하게 사용이 가능할 것입니다.

 

 

 

 

 

 

 

 

728x90
반응형

댓글