우리는 거의 모든 프로그래밍 언어의 루프에 대해 배웠습니다. 따라서 기본적으로 반복 작업이 있을 때마다 루프 구현을 시작합니다. 그러나 많은 반복(수백만/수십억 행)을 처리할 때 루프를 사용하는 것은 정말 고통스럽고 몇 시간 동안 정체되어 나중에 작동하지 않는다는 것을 깨닫게 될 수 있습니다. Python에서 벡터화를 구현하는 것이 매우 중요합니다.
벡터화는 데이터 세트에 (NumPy) 배열 작업을 구현하는 기술입니다. 뒤에서는 한 번에 한 행씩 작동하는 'for' 루프와는 달리 배열이나 계열의 모든 요소에 대해 동시에 작동합니다.
이 블로그에서는 Python 루프를 벡터화로 쉽게 대체할 수 있는 몇 가지 사용 사례를 살펴보겠습니다. 이렇게 하면 시간을 절약하고 코딩에 더욱 능숙해지는 데 도움이 됩니다.
먼저, 루프와 벡터를 사용하여 Python에서 숫자의 합을 구하는 기본 예를 살펴보겠습니다.
import time start = time.time() # 遍历之和 total = 0 # 遍历150万个数字 for item in range(0, 1500000): total = total + item print('sum is:' + str(total)) end = time.time() print(end - start) #1124999250000 #0.14 Seconds
import numpy as np start = time.time() # 向量化和--使用numpy进行向量化 # np.range创建从0到1499999的数字序列 print(np.sum(np.arange(1500000))) end = time.time() print(end - start) ##1124999250000 ##0.008 Seconds
벡터화의 실행 시간은 범위 함수를 사용한 반복에 비해 약 18배입니다. 이 차이점은 Pandas DataFrame으로 작업할 때 더욱 분명해집니다.
데이터 과학에서 개발자는 Pandas DataFrame으로 작업할 때 루프를 사용하여 수학 연산을 위한 새로운 파생 열을 만듭니다.
아래 예에서는 이러한 사용 사례에서 루프가 벡터화로 쉽게 대체될 수 있음을 알 수 있습니다.
DataFrame은 행과 열 형태의 표 형식 데이터입니다.
우리는 0에서 50 사이의 임의의 값으로 채워진 500만 개의 행과 4개의 열이 있는 pandas 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, 5) df.head()
'd' 열과 'c' 열의 비율을 찾기 위해 'ratio' 열을 새로 생성하겠습니다.
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) ### 109 Seconds
start = time.time() df["ratio"] = 100 * (df["d"] / df["c"]) end = time.time() print(end - start) ### 0.12 seconds
DataFrame에서 분명한 개선을 볼 수 있는데, 벡터화는 Python의 루프에 비해 거의 1000배 빠릅니다.
우리는 "if-else" 유형 논리를 사용해야 하는 많은 작업을 구현했습니다. 이 논리를 Python의 벡터화된 작업으로 쉽게 대체할 수 있습니다.
더 잘 이해하려면 아래 예를 살펴보세요(사용 사례 2에서 생성된 DataFrame을 사용하겠습니다).
종료된 열 'a'의 일부 조건을 기반으로 새 열 'e'를 생성하는 방법을 상상해 보세요.
import time start = time.time() # Iterating through DataFrame using iterrows 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) ### Time taken: 177 seconds
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) ## 0.28007707595825195 sec
if-else 문이 있는 Python 루프와 비교할 때 벡터화된 작업은 루프보다 600배 빠릅니다.
딥 러닝을 위해서는 여러 개의 복잡한 방정식을 풀어야 하며, 이는 수백만 행의 방정식을 풀어야 합니다. 이러한 방정식을 풀기 위해 Python에서 루프를 실행하는 것은 매우 느립니다. 이 시점에서는 벡터화가 최선의 솔루션입니다.
예를 들어 다음 다중 선형 회귀 방정식에서 수백만 행의 y 값을 계산하려고 합니다.
루프를 벡터화로 대체할 수 있습니다.
m1,m2,m3...의 값은 x1,x2,x3...에 해당하는 수백만 개의 값을 사용하여 위 방정식을 풀어 결정됩니다. (단순화를 위해 간단한 곱셈 단계를 살펴보세요.)
>>> import numpy as np >>> # 设置 m 的初始值 >>> m = np.random.rand(1,5) array([[0.49976103, 0.33991827, 0.60596021, 0.78518515, 0.5540753]]) >>> # 500万行的输入值 >>> x = np.random.rand(5000000,5)
import numpy as np m = np.random.rand(1,5) x = np.random.rand(5000000,5) 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[i] = total toc = time.process_time() print ("Computation time = " + str((toc - tic)) + "seconds") ####Computation time = 28.228 seconds
tic = time.process_time() #dot product np.dot(x,m.T) toc = time.process_time() print ("Computation time = " + str((toc - tic)) + "seconds") ####Computation time = 0.107 seconds
np.dot은 백엔드에서 벡터의 행렬 곱셈을 구현합니다. Python의 루프에 비해 165배 빠릅니다.
Python의 벡터화는 매우 빠르며 매우 큰 데이터 세트를 처리할 때는 루프보다 벡터화를 우선시하는 것이 좋습니다. 이런 식으로 시간이 지남에 따라 벡터화 아이디어에 따라 코드를 작성하는 데 점차 익숙해질 것입니다.
위 내용은 안녕히 가세요! Python 루프, 벡터화는 놀랍습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!