Python中的矢量化和廣播

已發表: 2020-12-01

矢量化和廣播是在使用 Numpy 進行數學運算時加快計算時間和優化內存使用的方法。 這些方法對於確保降低時間複雜度以使算法不會面臨任何瓶頸至關重要。 這種優化的操作對於應用程序的可擴展性是必要的。 我們將介紹這兩種技術並實現一些示例。

在本教程結束時,您將掌握以下知識:

  • Numpy 如何處理向量化
  • 有和沒有矢量化的時間差
  • 什麼是廣播
  • 廣播與通常的矩陣乘法有何不同

矢量化

很多時候,我們需要對數組進行數學運算——比如數組乘法。 現在,一種非向量化的方法是使用循環進行元素乘法。 以這種方式實現它會導致多次執行相同的乘法運算,如果數據量太大,這將浪費計算資源。 讓我們快速瀏覽一下。

非矢量化方式:

隨機導入

a = [random.randint( 1 , 100 ) for _ in range( 10000 )]
b = [random.randint( 1 , 100 ) for _ in range( 10000 )]
%timeit [i*j for i, j in zip(a,b)]

#輸出:
>> 1000 個循環,最好的3 個每個循環658 µs

矢量化方式:

numpy導入np
a = np.array([random.randint( 1 , 100 ) for _ in range( 10000 )])
b = np.array([random.randint( 1 , 100 ) for _ in range( 10000 )])
%timeit a*b

#輸出:
>> 100000循環, 3 個中最好的每個循環7.25 µs

如我們所見,經過的時間從 658 微秒變為僅 7.25 微秒。 這是因為當我們說a = np.array([])時,所有操作都由 numpy 內部處理。 當我們執行a*b,numpy 在內部通過向量化的方式一次將整個數組相乘。

在這裡,我們使用 %timeit 魔術命令來計時進程的執行時間,這可能在您的機器上有所不同。

讓我們看一下維度為 (nx1) 和 (1xm) 的 2 個向量的外積的另一個示例。 輸出將是 (nxm)。

進口時間
導入numpy
導入數組
a = array.array( 'i' , [random.randint( 1 , 100 ) for _ in range( 100 )])
b = array.array( 'i' , [random.randint( 1 , 100 ) for _ in range( 100 )])

T1 = time.process_time()
c = numpy.zeros(( 200 , 200 ))

對於範圍內(len(a)):
對於範圍內j (len(b)):
c[i][j]= a[i]*b[j]

T2 = time.process_time()

print( f”計算時間 = { 1000 *(T2-T1)} ms” )

#輸出:
>> 計算時間 = 6.819299000000001毫秒

現在,讓我們用 Numpy 來做吧,

T1 = time.process_time()
c = numpy.outer(a, b)
T2 = time.process_time()

print( f”計算時間 = { 1000 *(T2-T1)} ms” )

#輸出:
>> 計算時間 = 0.2256630000001536 ms

正如我們再次看到的,Numpy 通過矢量化更快地處理相同的操作方式。

必讀:現實世界中令人著迷的 Python 應用程序

廣播

所以到目前為止,我們看到了使用相同大小數組的示例。 如果數組的大小不同怎麼辦? 這裡是 Numpy 的另一個很棒的功能,廣播,出現的地方。

廣播是向量化的另一個擴展,其中數組不需要具有相同的大小,以便對其執行加法、減法、乘法等操作。讓我們通過一個非常簡單的數組和標量相加示例來理解這一點。

a = np.array([ 1 , 1 , 1 , 1 ])
一個+ 5

#輸出:
數組([ 6 , 6 , 6 , 6 ])

正如我們所見,標量 5 被添加到所有元素中。 那麼它是怎麼發生的呢?

想像一下這個過程,你可以認為標量 5 重複 4 次以形成一個數組,然後將其添加到數組 a 中。 但請記住,Numpy 不會創建任何此類只會佔用內存的數組。 Numpy 只是“廣播”或複制標量 5 到 4 個位置以將其添加到數組 a。

讓我們再舉一個簡單的例子。

a = np.ones(( 3 , 3 ))
b = np.ones( 3 )
a+b

#輸出:
>> 數組([[ 2. , 2. , 2. ],
[ 2. , 2. , 2. ],
[ 2. , 2. , 2. ]])

在上面的示例中,形狀 (3,1) 的數組被廣播到 (3,3) 以匹配數組 a。

但這是否意味著任何維度的數組都可以通過廣播來匹配任意維度的數組呢?

不!

廣播規則

Numpy 遵循一組簡單的規則來確保只廣播符合條件的數組。 讓我們來看看。

廣播規則說要操作的 2 個數組必須具有相同的維度,或者如果它們中的任何一個為 1。

讓我們看看這是在行動。

示例 1:

考慮以下維度數組:

a = 3 x 4 x 7

b = 3 x 4 x 1

這裡 b 的最後一個維度將被廣播以匹配 a 到 7 的維度。

因此,結果 = 3 x 4 x 7

示例 2:

a = 3 x 4 x 7

b = 4

現在,a 和 b 的維數不相等。 在這種情況下,維數較少的數組將用 1 填充。

所以,在這裡,b 的第一個和最後一個維度都是 1,因此它們將被廣播以匹配 a 到 3 和 7。

因此,結果 = 3 x 4 x 7。

閱讀: Python 教程

示例 3:

a = 3 x 4 x 1 x 5

b = 3 x 1 x 7 x 1

同樣,b 的第二個和最後一個維度將被廣播以匹配 a 的 4 和 5。此外,a 的第三個維度將被廣播以匹配 b 的 7。

因此,結果 = 3 x 4 x 7 x 5

現在讓我們看看條件何時失敗:

示例 4:

a = 3 x 4 x 7 x 5

b = 3 x 3 x 7 x 4

在這裡,b的第二個和第四個維度與a不匹配,也不是1。在這種情況下,Python會拋出一個值錯誤:

ValueError 操作無法形狀 3、4、7、5 3、3、7、4 一起廣播_ _ _ _ _ _

示例 5:

a = 3 x 4 x 1 x 5

b = 3 x 2 x 3

結果:值錯誤

在這裡,第二個維度也不匹配,並且它們中的任何一個都不是 1。

在你走之前

矢量化和廣播都是 Numpy 優化和更高效處理的方法。 這些概念應該牢記在心,尤其是在處理圖像數據和神經網絡中非常常見的矩陣和 n 維數組時。

如果您想了解 Python、數據科學,請查看 IIIT-B 和 upGrad 的數據科學 PG 文憑,該文憑專為在職專業人士而設,提供 10 多個案例研究和項目、實用的實踐研討會、與行業專家的指導,與行業導師一對一,400 多個小時的學習和頂級公司的工作協助。

Python中的向量化是什麼?

Numpy 是一個 Python 包,它提供了幾個標準的數學函數,可以在不需要循環的情況下對大型數據數組進行快速操作,包括矢量化。 矢量化用於在不使用循環的情況下加速 Python 程序。 使用這種方法可以幫助減少執行代碼所花費的時間。 對向量執行各種操作,例如向量的點積,也稱為標量積,因為它產生單個輸出,外積,其結果是維度等於長度 x 長度的方陣向量,逐元素乘法,它產生具有相同索引的元素。

什麼是 Python 中的廣播?

廣播一詞是指 Numpy 在導致特定限制的算術運算期間如何管理具有不同維度的數組; 較小的陣列在巨大的陣列中廣播,以便它們的形式是一致的。 廣播允許您對數組操作進行向量化,以便循環在 C 中進行,而不是像 Numpy 那樣在 Python 中進行。 它在不創建不必要的數據副本的情況下實現了這一點,從而實現了高效的算法實現。 在某些情況下,廣播是一個負面的想法,因為它會導致浪費的內存消耗,從而減慢處理速度。

NumPy 在 Python 中的用途是什麼?

NumPy 或 Numerical Python 是一個免費的開源 Python 庫,幾乎被每個研究和工程分支所使用。 NumPy 庫包括多維數組和矩陣數據結構,並提供有效操作數組(同質 n 維數組對象)的方法。 用戶可以使用 NumPy 對數組執行廣泛的數學運算。 它通過強大的數據結構增強了 Python,這些數據結構提供了使用數組和矩陣的高效計算,以及處理這些數組和矩陣的大量高級數學函數庫。