2011-04-13 130 views
1

從我身邊其他愚蠢的問題;)我有與LEN(x)= LEN(Y)= 7'700'000下面的代碼片段一些問題:減少時間久for循環Python中

from numpy import * 

for k in range(len(x)): 
    if x[k] == xmax: 
     xind = -1 
    else: 
     xind = int(floor((x[k]-xmin)/xdelta)) 
    if y[k] == ymax: 
     yind = -1 
    else: 
     yind = int(floor((y[k]-ymin)/ydelta)) 

    arr = append(arr,grid[xind,yind]) 

所有變量都是浮點數或整數,除了arrgridarr是一維數組,而grid是二維數組。

我的問題是,它需要很長時間來運行循環(幾分鐘)。任何人都可以解釋我,爲什麼需要這麼長時間?有沒有人有建議?即使我試圖通過arange()交換range(),那麼我只能節省一些時間。

謝謝。

1st EDIT 對不起。忘了告訴我進口numpy

第二編輯

我有一個2D網格的幾個問題。網格的每個單元格都存儲了一個值。我必須找出該點具有哪個位置並將該值應用於新陣列。這是我的問題和我的想法。

如果你想更好地理解它,請看圖片。單元格的值用不同的顏色表示。

idea

+1

什麼是'append'? – delnan 2011-04-13 20:19:15

+0

你的意思是'xrange'? – 2011-04-13 20:20:05

回答

4

如何像:

import numpy as np 
xind = np.floor((x-xmin)/xdelta).astype(int) 
yind = np.floor((y-ymin)/ydelta).astype(int) 

xind[np.argmax(x)] = -1 
yind[np.argmax(y)] = -1 

arr = grid[xind,yind] 

注:如果您使用numpy的,如果你想有效地做事情不要像對待Python列表的數組。

+0

+1,尤其是對於「如果您使用numpy,請不要像列表一樣處理數組」!儘管如此,'np.floor((x-xmin)/ xdelta)'相當於'(x - xmin)// xdelta'(並且邊緣更快,在這種情況下並不重要)。 – 2011-04-13 21:00:08

+0

謝謝。這真的非常好! – ahelm 2011-04-13 21:09:22

+0

@PateToni:沒問題。 Numpy是一個非常強大的軟件包,但它涉及的問題思考方式與您使用其他Python數據結構時的方式不同。切換你想要的時間需要一些時間,但是當你掌握它的時候,你會在你的代碼中獲得巨大的提速,並一次一個元素遍歷數組。 – JoshAdel 2011-04-13 21:42:18

1
for x_item, y_item in zip(x, y): 
    # do stuff. 

還有izip因爲如果你不希望產生一個巨大的額外列表。

0

我看不出一個明顯的問題,除了數據的大小。你的電腦能夠把所有東西都放在內存中嗎?如果沒有,你可能會在交換內存中「跳來跳去」,這總是會很慢。如果完整的數據在內存中,請嘗試psyco。它可能會加快你的計算。

-1

x's lenght是700萬?我想這就是爲什麼! 迭代次數7百萬次,

可能你應該做另一種循環。 它真的需要循環超過7米?

0

我懷疑問題可能是要存儲的結果的方式:

arr = append(arr,grid[xind,yind]) 

The docs for append說,它返回:

arrvalues副本附加 到axis。請注意,append確實不會在原地發生: 已分配和填充。

這意味着您將在每次迭代中釋放並分配更大和更大的數組。我建議先分配一個正確大小的數組,然後用每次迭代中的數據填充它。例如:

arr = empty(len(x)) 

for k in range(len(x)): 
    ... 
    arr[k] = grid[xind,yind]