【Python】瘋狂的加速函數(shù)!
einsum函數(shù)

在平時的工作中,包括時間序列等的建模中,我們常常會涉及到線性或者Multilinear代數(shù)的計算,很多時候包括我在內(nèi)也喜歡偷懶使用numpy來處理,個人覺得還是可以的,但有的朋友覺得這個看起來可讀性會差一些,并且速度上也差一些,今天就推薦一個新的函數(shù)einsum函數(shù)。
通過einsum函數(shù),我們可以寫出可讀性更好,更加高效的函數(shù)。


關(guān)于einsum函數(shù)
einsum函數(shù)一般會用于向量,矩陣,張量的計算中。

如果輸入的是標量(scalar),我們就可以空著,因為它沒有下標。
einsum函數(shù)優(yōu)勢
1.速度優(yōu)勢
因為numpy很多是用C寫的。
如果我們使用Python循環(huán)時,所有數(shù)據(jù)操作都在Python解釋器中進行。
當使用內(nèi)置numpy函數(shù)時,它發(fā)生在C中,這就是numpy速度更快的原因。
使用einsum時,numpy會在C中處理數(shù)據(jù)一次并返回最終結(jié)果,而使用多個numpy函數(shù)會花費更多時間返回多個值。
2.可讀性優(yōu)勢
einsum的代碼可讀性會更強,能大大提高代碼的可讀性和效率。

比較循環(huán),numpy中的其它函數(shù),einsum
從下面的案例中,我們發(fā)現(xiàn)einsum比numpy快樂將近30倍,比循環(huán)快了500-600倍。
import?numpy?as?np
A?=?np.random.rand(1000,1000)
B?=?np.random.rand(1000,1000)
%%time
#?Using?loops
s?=?0
n,?m?=?A.shape
for?i?in?range(n):
????for?j?in?range(m):
????????s?+=?A[i,?j]*B[i,?j]?
s
#?CPU?times:?user?596?ms,?sys:?5.79?ms,?total:?602?ms
#?Wall?time:?607?ms
#?249760.77497519302
CPU times: user 596 ms, sys: 5.79 ms, total: 602 ms
Wall time: 607 ms
249760.77497519302
%%time
#?Using?built-in?numpy?functions
np.trace(np.dot(A.T,?B))
#?CPU?times:?user?113?ms,?sys:?8.54?ms,?total:?121?ms
#?Wall?time:?38.1?ms
#?249760.7749751993
CPU times: user 113 ms, sys: 8.54 ms, total: 121 ms
Wall time: 38.1 ms
249760.7749751993
%%time
#?Using?einsum
np.einsum('ij,ij->',?A,B)
#?CPU?times:?user?1.64?ms,?sys:?689?μs,?total:?2.33?ms
#?Wall?time:?1.19?ms
#?249760.7749751993
CPU times: user 1.64 ms, sys: 689 μs, total: 2.33 ms
Wall time: 1.19 ms
249760.7749751993
所有涉及到矩陣,向量,張量等計算的問題。

Write Better And Faster Python Using Einstein Notation
往期精彩回顧
評論
圖片
表情
