我想在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的更快?
我想在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的更快?
使用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]])
我使用numpy的用於圖像處理。在我用於(x in row)之前(對於列y中的y)(反之亦然,你會明白)。
這對於小圖像來說很好,但會很高興地消耗內存。相反,我切換到numpy.array。快多了。
根據循環中實際發生的情況,是的。
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]]
應該清楚如何分析一個或多個陣列時,索引可以顯着提高你的速度。這是一個強大的工具...
如果這些是聚合統計,請考慮使用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
你在做什麼算盤? – aganders3
這取決於,您必須確定哪個計算所花的時間最長。如果訪問foo和bar的時間過長,因爲它必須等待將其從硬盤驅動器的讀寫頭中拉出來,那麼優化迴路的性質將集中在錯誤的區域。 –