2017-04-22 59 views
1

有沒有一種方法可以在Python中更快地計算Cobb-Douglas utility function。我運行數百萬次,所以提高速度會有所幫助。該函數將quantity_list的元素提升爲指數列表的相應元素的權力,然後乘以所有得到的元素。兩個列表性能的Python冪運算

n = 10 

quantities = range(n) 
exponents = range(n) 

def Cobb_Douglas(quantities_list, exponents_list): 
    number_of_variables = len(quantities_list) 
    value = 1 
    for variable in xrange(number_of_variables): 
     value *= quantities_list[variable] ** exponents_list[variable] 
    return value 

t0 = time.time() 
for i in xrange(100000): 
    Cobb_Douglas(quantities, exponents) 
t1 = time.time() 
print t1-t0 
+1

看看快速數字操作'numpy'庫。 – BrenBarn

+1

Numpy在這種情況下速度較慢 – user58925

+0

你見過[this](https://stackoverflow.com/questions/31027863/cobb-douglas-functions-slows-running-tremendously-how-to-expedite-a-non-線性)問題?它提供了一個潛在的加速。 – Darkstarone

回答

1

迭代器是你的朋友。我得到了我的計算機上的28%的加速通過你的循環切換到此:

for q, e in itertools.izip(quantities_list, exponents_list): 
    value *= q ** e 

切換你的循環到functools.reduce電話時,我也得到了類似的結果,所以這是不值得提供的代碼示例。


一般來說,numpy是快速算術運算正確的選擇,但numpy最大的整數類型爲64位,這將不會保持你的榜樣結果。如果您使用的是不同的數值範圍或算術類型,numpy爲王:

quantities = np.array(quantities, dtype=np.int64) 
exponents = np.array(exponents, dtype=np.int64) 

def Cobb_Douglas(quantities_list, exponents_list): 
    return np.product(np.power(quantities_list, exponents_list)) 
# result: 2649120435010011136 
# actual: 21577941222941856209168026828800000 
+0

謝謝。我也得到了itertools 10-25%的加速,但幾乎5倍的numpy減速..我使用Mac – user58925

+1

怪異的。你計算的實際數據集是什麼?它的大小和數據類型可以有所作爲。 –

1

夫婦的建議:

  1. 使用numpy的

  2. 矢量化代碼

  3. 如果數量很大,而且沒有什麼會變爲零或負數,請在日誌空間中工作。

我有大約15%的加速本地使用:

def np_Cobb_Douglas(quantities_list, exponents_list): 
    return np.product(np.power(quantities_list, exponents_list)) 

約40%使用:

def np_log_Cobb_Douglas(quantities_list, exponents_list): 
    return np.exp(np.dot(np.log(quantities_list), np.log(exponents_list))) 

最後但並非最不重要的,應該有你的科布的一些縮放 - 道格拉斯參數,所以你不會遇到溢出錯誤(如果我正確記住我的前奏宏)。

+0

謝謝。對於我的應用程序,numpy相當慢.. – user58925

+0

也許你可以擴展你的應用程序/實現是什麼?使用矢量/ BLAS做這件事應該提供一個體面的加速,這是我用你提供的最小代碼看到的。 –