2016-02-28 63 views
0

我完全是python的新手。我試圖做一個非常簡單的事情,評估一個非平凡的函數,它將浮點數作爲2D網格上的輸入。下面的代碼完全符合我的要求,但由於double for循環,所以速度很慢。在python中矢量化一個簡單的函數:避免雙循環

import numpy as np 
from galpy.potential import RazorThinExponentialDiskPotential 


R = np.logspace(0., 2., 10) 
z=R 

#initialize with default values for this example 
potfunc=RazorThinExponentialDiskPotential() 

pot=np.zeros((R.size, z.size)) 


for i in range(0, R.size): 
    for j in range(0, z.size): 
     pot[i,j]=potfunc(R[i],z[j]) 

最後,陣列鍋包含我想要的所有信息,但現在我想提高效率。我知道純Python很慢,特別是在循環(比如IDL)上,所以我檢查了np.vectorize,但它只是一個蟒蛇循環。 問題是,potfunc似乎不接受數組,但只是普通的標量。

我該如何優化這個簡單的程序?

非常感謝提前。

回答

0

標準的方式做到這一點是使用meshgrid

r,z=np.meshgrid(R,Z) 
    pot=potfunc(r,z) 

你必須避免循環numpy的陣列上,否則你會失去所有矢量化的效率。

+0

不幸的是potfunc只接受標量,而不是矢量... – andrea

0

如果你不能手工矢量化函數(也許你可以繼承Razor ..類並重寫函數),你可以使用multiprocessing。相反,我的簡單工作器功能的,你可以使用此功能,你喜歡:

from multiprocessing import pool 
import numpy as np 
def worker(x): 
    ai,bj = x 
    return ai + bj 

def run_pool(): 
    a = np.linspace(0,10,10) 
    b = np.logspace(0,10,len(a)) 
    vec = [(a[i],b[j]) for i in range(len(a)) for j in range(len(b))] 
    p = pool.Pool(processes=4) # as many cores as you have 
    print(p.map(worker,vec)) 
    p.close() 
    p.join() 

run_pool() 

但是你想想加快東西之前,分析將是一件好事。我很肯定,在你的情況下,函數本身就是瓶頸。因此,無論是使用編譯器語言重寫它,還是使用矢量化,或者使用所有核心。