2012-10-11 52 views
3

我想在Python中做一些數據處理,並且我有一個嵌套的循環,它執行一些算術計算。內循環執行20.000倍所以下面的代碼段需要很長的時間:是否可以進一步優化這個數字運算算法?

for foo in foo_list: 
    # get bar_list for foo 
    for bar in bar_list: 
     # do calculations w/ foo & bar 

可這循環中使用numpy的或SciPy的更快?

+3

你在做什麼算盤? – aganders3

+1

這取決於,您必須確定哪個計算所花的時間最長。如果訪問foo和bar的時間過長,因爲它必須等待將其從硬盤驅動器的讀寫頭中拉出來,那麼優化迴路的性質將集中在錯誤的區域。 –

回答

2

使用numpy的:

import numpy as np 
foo = np.array(foo_list)[:,None] 
bar = np.array(bar_list)[None,:] 

然後

foo + bar 

或其他操作創建與相應的結果的陣列len(foo) * len(bar)

實施例:

>>> foo_list = [10, 20, 30] 
>>> bar_list = [4, 5] 
>>> foo = np.array(foo_list)[:,None] 
>>> bar = np.array(bar_list)[None,:] 
>>> 2 * foo + bar 

array([[24, 25], 
     [44, 45], 
     [64, 65]]) 
0

我使用numpy的用於圖像處理。在我用於(x in row)之前(對於列y中的y)(反之亦然,你會明白)。

這對於小圖像來說很好,但會很高興地消耗內存。相反,我切換到numpy.array。快多了。

0

根據循環中實際發生的情況,是的。
numpy允許使用數組和矩陣,這可以使索引更快地執行代碼,並且在某些情況下可以消除循環。

索引例如:

import magic_square as ms 

a = ms.magic(5) 

print a # a is an array 
[[17 24 1 8 15] 
[23 5 7 14 16] 
[ 4 6 13 20 22] 
[10 12 19 21 3] 
[11 18 25 2 9]] 

# Indexing example. 
b = a[a[:,1]>10]*10 

print b 
[[170, 240, 10, 80, 150], 
[100, 120, 190, 210, 30], 
[110, 180, 250, 20, 90]] 

應該清楚如何分析一個或多個陣列時,索引可以顯着提高你的速度。這是一個強大的工具...

0

如果這些是聚合統計,請考慮使用Python Pandas。例如,如果你想要做的事,以各種不同的(foo, bar)對,你可以組,通過這些項目,然後應用矢量NumPy的操作:

import pandas, numpy as np 
df = pandas.DataFrame(
         {'foo':[1,2,3,3,5,5], 
         'bar':['a', 'b', 'b', 'b', 'c', 'c'], 
         'colA':[1,2,3,4,5,6], 
         'colB':[7,8,9,10,11,12]}) 
print df.to_string() 

# Computed average of 'colA' weighted by values in 'colB', for each unique 
# group of (foo, bar). 
weighted_avgs = df.groupby(['foo', 'bar']).apply(lambda x: (1.0*x['colA']*x['colB']).sum()/x['colB'].sum()) 

print weighted_avgs.to_string() 

這將打印的只是數據對象如下:

bar colA colB foo 
0 a  1  7 1 
1 b  2  8 2 
2 b  3  9 3 
3 b  4 10 3 
4 c  5 11 5 
5 c  6 12 5 

這是分組,聚合輸出

foo bar 
1 a  1.000000 
2 b  2.000000 
3 b  3.526316 
5 c  5.521739