Rumah >pembangunan bahagian belakang >Tutorial Python >Menggunakan vektorisasi untuk menggantikan gelung dalam python
Semua bahasa pengaturcaraan tidak dapat dipisahkan daripada gelung. Jadi, secara lalai, kami mula melaksanakan gelung apabila terdapat operasi berulang. Tetapi apabila kita berhadapan dengan sejumlah besar lelaran (berjuta-juta/berbilion baris), menggunakan gelung adalah satu jenayah. Anda mungkin terperangkap selama beberapa jam, hanya untuk menyedari kemudian bahawa ia tidak berfungsi. Di sinilah pelaksanaan vektorisasi dalam python menjadi sangat kritikal.
Vektorisasi ialah teknik untuk melaksanakan operasi tatasusunan (NumPy) pada set data. Di sebalik tabir, ia menggunakan operasi kepada semua elemen tatasusunan atau siri sekali gus (tidak seperti gelung "untuk" yang mengendalikan satu baris pada satu masa).
Seterusnya kami menggunakan beberapa kes penggunaan untuk menunjukkan apa itu vektorisasi.
##使用循环 import time start = time.time() # iterative sum total = 0 # iterating through 1.5 Million numbers 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() # vectorized sum - using numpy for vectorization # np.arange create the sequence of numbers from 0 to 1499999 print(np.sum(np.arange(1500000))) end = time.time() print(end - start) ##1124999250000 ##0.008 Seconds
Masa pelaksanaan vektorisasi dikurangkan berbanding lelaran menggunakan fungsi julat Kira-kira 18 kali. Perbezaan ini menjadi lebih ketara apabila menggunakan Pandas DataFrame.
Dalam sains data, apabila bekerja dengan Pandas DataFrame, pembangun menggunakan gelung untuk mencipta lajur terbitan baharu melalui operasi matematik.
Dalam contoh di bawah, kita dapat melihat betapa mudahnya untuk menggantikan gelung dengan vektorisasi untuk kes penggunaan sedemikian.
DataFrame ialah data jadual dalam bentuk baris dan lajur.
Kami mencipta DataFrame panda dengan 5 juta baris dan 4 lajur yang diisi dengan nilai rawak antara 0 dan 50.
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()
Buat "nisbah" lajur baharu untuk mencari nisbah lajur "d" dan "c".
## 循环遍历 import time start = time.time() # 使用 iterrows 遍历 DataFrame for idx, row in df.iterrows(): # 创建一个新列 df.at[idx, 'ratio' ] = 100 * (row[ "d" ] / row[ "c" ]) end = time.time() print (end - start) ### 109 秒
## 使用矢量化 start = time.time() df[ "ratio" ] = 100 * (df[ "d" ] / df[ "c" ]) end = time.time() print (end - start) ### 0.12 秒
Kita boleh melihat peningkatan yang ketara dengan DataFrame, dengan operasi vektor mengambil masa hampir 1000 kali lebih pantas berbanding gelung dalam Python.
Kami telah melaksanakan banyak operasi yang memerlukan kami menggunakan logik jenis "If-else". Kita boleh dengan mudah menggantikan logik ini dengan operasi vektor dalam python.
Mari kita lihat contoh berikut untuk memahaminya dengan lebih baik (kita akan menggunakan DataFrame yang kita buat dalam use case 2):
Bayangkan kita ingin menggunakan lajur "a" sedia ada Buat a lajur baharu "e" dengan beberapa syarat pada
## 使用循环 import time start = time.time() # 使用 iterrows 遍历 DataFrame 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) ### 耗时:166 秒
## 矢量化 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() 打印(结束 - 开始) ## 0.29007707595825195 秒
Operasi vektor mengambil masa 600 kali lebih pantas berbanding gelung ular sawa menggunakan pernyataan if-else.
Pembelajaran mendalam memerlukan kita menyelesaikan berbilang persamaan kompleks dan terdapat berjuta-juta dan berjuta-juta persamaan untuk diselesaikan Masalah berbilion baris. Menjalankan gelung untuk menyelesaikan persamaan ini dalam Python adalah sangat perlahan dan vektorisasi adalah penyelesaian terbaik.
Sebagai contoh, untuk mengira nilai-y untuk berjuta-juta baris dalam persamaan regresi linear berbilang berikut:
Kita boleh vektorkan bukannya gelung .
Nilai m1, m2, m3... ditentukan dengan menyelesaikan persamaan di atas menggunakan berjuta-juta nilai yang sepadan dengan x1, x2, x3.. .
import numpy as np # 设置 m 的初始值 m = np.random.rand( 1 , 5 ) # 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" ) ####计算时间 = 27.02 秒
## 矢量化 tic = time.process_time() #dot product np.dot(x,mT) toc = time.process_time() print ( "计算时间 = " + str ((toc - tic)) + "seconds" ) ####计算时间 = 0.107 秒
np.dot melaksanakan pendaraban matriks vektor di bahagian belakang. Ia adalah 165 kali lebih pantas berbanding gelung dalam Python.
Vektorisasi dalam python adalah sangat pantas dan harus diutamakan berbanding gelung apabila kita berurusan dengan set data yang sangat besar.
Apabila anda mula melaksanakannya dari semasa ke semasa, anda akan terbiasa berfikir mengikut baris kod vektor.
Atas ialah kandungan terperinci Menggunakan vektorisasi untuk menggantikan gelung dalam python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!