2015-03-02 39 views
0

假設幾次被稱爲多次的函數。這些函數在3d矢量(1x3數組)上執行諸如乘法,除法,加法等操作。使用python和numpy進行簡單到中等計算的有效方法

考慮:

import numpy as np 
import math 
x = [0,1,2] 
y = [3,2,1] 
a = 1.2 

根據我的測試,它是更快的Python數學庫做:

math.sin(a) 

比numpy的做:

np.sin(a) 

此外,使用中討論的方法,python比np.linalg.norm更簡單的算法(如標準化)更快。

現在,如果我們爲數據添加一些複雜性,比如對3d執行矩陣乘法,那麼我們有一個3x3的旋轉矩陣,然後乘以另一個矩陣並進行轉置,numpy開始獲得優勢。

目前,比如做業務:

L = math.sqrt(V[0] * V[0] + V[1] * V[1] + V[2] * V[2]) 
V = (V[0]/L, V[1]/L, V[2]/L) 

快得多一再呼籲的時候(我從沒有開銷承擔創建numpy的陣列)。

但是,爲了使用numpy矩陣函數,數組需要是numpy。使用np.asarray()具有很大的開銷,這使得根本不使用numpy之間的效率邊界,接受創建數組的開銷,或接受標量上的numpy數學函數的效率並僅使用numpy。

當然,我可以嘗試所有這些方法,但在大型算法中,可能的組合太多了。在這種情況下是否有任何策略能夠在python和numpy之間高效切換?

編輯: 從一些評論看來,這個問題似乎還不夠清楚。我知道numpy對大套裝更有效率,這就是爲什麼這個問題存在。該算法不只是計算正弦。下面的代碼可能更容易理解:

x = [2,1,2] 
math.sin(x[0]) 
L = math.sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]) 
V = (x[0]/L, x[1]/L, x[2]/L) 
math.sin(V[0]) 
#Do something else here 
+0

您是如何比較執行速度的?如果你使用矢量化(因爲你總是應該用numpy,也就是說,而不是運行'np.sin(a)'幾千次,運行'np.sin(np.repeat(1.2,1000))'一次),我懷疑它是比Python自己的「數學」慢。 – Phillip 2015-03-02 08:55:33

+0

@Phillip我用timeit, – user1938107 2015-03-02 09:01:38

+0

timeit.timeit('import numpy as np; import math; math.sin(234.2343),100000')並在math.sin和np.sin之間切換 – user1938107 2015-03-02 09:02:21

回答

-1

當單值和小陣列工作時,np.array開銷肯定會減慢速度相比,使用math.等價物。但有了很多價值,陣列方法很快就會變得更好。

例如,在Ipython我可以一次sin 50個值:

In [444]: %%timeit x=np.arange(50) 
np.sin(x) 
100000 loops, best of 3: 8.5 us per loop 

In [445]: %%timeit x=range(50) 
[math.sin(i) for i in x] 
100000 loops, best of 3: 18.1 us per loop 

V計算比

Va=Va/math.sqrt((Va*Va).sum()) 

快20倍,但如果我這樣做對20組值,時代幾乎相等。我不必改變表達式來處理Va=np.ones((20,3), float)。要定時你的V我不得不把它包裝在一個功能和時間[foo(i) for i in V]

你甚至可以通過僅索引一次來獲得更多的速度,例如,

v1, v2, v3 = V 
L = math.sqrt(v1*v1+ v2*v2+v3*v3) 
V = (v1/L, v2/L, v3/L) 

當使用數組而不是列表時,我希望獲得更多的收益。

相關問題