2011-02-04 53 views
2

根據回答from this question,我從一維數組創建了一個網格,該數組修改了一個值及其周圍的鄰居;如果該值在另一個數組中找到。主值由特定的百分比轉換,周圍的元素由另一個轉換。Python 3.1網格模擬問題

但是,如何確保在下次樣本迭代過程中更改的值不會再次被轉換。

下面的示例代碼。感謝您的時間!

import numpy as np 


def grid(array,samples,details): 

    #Sides of the square (will be using a squarable number 
    Width = (len(array)) ** 0.5 
    #Convert to grid 
    Converted = array.reshape(Width,Width) 
    #Conversion details 
    Change = [details[1]] + [details[2]] 
    nrows, ncols = Converted.shape 

    for value in samples: 

     #First instance where indexing returns it 
     i,j = np.argwhere(Converted == value)[0] 

     #Prevent indexing outside the boudaries of the 
     #array which would cause a "wraparound" assignment 
     istart, istop = max(i-1, 0), min(i+2, nrows) 
     jstart, jstop = max(j-1, 0), min(j+2, ncols) 


     #Set the value within a 3x3 window to their "new_value" 
     for elem in Converted[istart:istop, jstart:jstop]: 

      Converted[elem] = elem + (elem * (value * ((Change[1]/100)) 

     #Set the main value to the new value 
     Converted[i,j] = value + (value * ((Change[0])/100)) 


    #Convert back to 1D list 
    Converted.tolist() 

    return (Converted) 


a = [16,2,20,4,14,6,70,8,9,100,32,15,7,14,50,20,17,10,9,20,7,17,50,2,19,20,21,22,23,24,25] 
samples = [2, 7] 
grid_details = [10,50,100] 

result = grid(a,samples,grid_details) 
+0

我不想避免修改以前修改過的網格中的任何值,不管它是主值還是周圍值 – jimy 2011-02-04 04:48:09

回答

3

首先,讓我們走過的部分代碼段......有幾個問題,你現在已經寫了什麼......

順便說一句,有Python中的鬆散約定預留大寫字母和駱駝名稱的類。 (您經常會看到類似foo = FooBar(baz)的代碼,其中fooFooBar類的一個實例。)調用變量Converted而不是converted沒什麼問題,但是您將看到的大多數代碼都將使用後一種形式。

所以,讓我們從這裏開始:

import numpy as np 
def grid(array,samples,details): 
    ... 

看來你在以後通過列表作爲array。因此,您需要將列表array轉換爲numpy.ndarray。 (否則,諸如array.reshape之類的東西就不會起作用。)您也可以考慮將變量名稱更改爲不如「array」的通用名稱。但是,現在,讓我們保持變量名稱相同。我也要去假設您想要浮點值,你按百分比後面乘以......讓我們將其更改爲:

import numpy as np 
def grid(array,samples,details): 
    array = np.asarray(array, dtype=np.float) 
    ... 

談完...

... 
    #Sides of the square (will be using a squarable number 
    Width = (len(array)) ** 0.5 
    #Convert to grid 
    Converted = array.reshape(Width,Width) 
    ... 

你有一個數學問題! 2x2數組爲4個元素,3x3數組爲9,4x4數組爲16,依此類推......如果要將一個序列重塑爲方形網格,則需要取平方根,而不是2除!讓我們改變,要:

... 
    #Sides of the square (will be using a squareable number) 
    Width = int(np.sqrt(array.size)) 
    #Convert to grid 
    Converted = array.reshape(Width,Width) 
    ... 

歸咎於睡眠不足......顯然,x**0.5是一樣的sqrt(x),我只是沒有看到第二個*。對於那個很抱歉!

下一頁:

... 
    Change = [details[1]] + [details[2]] 
    ... 

這是因爲只是在做這一樣的:

Change = details[1:3] 

在此之後的部分是好的,讓我們跳到下一個問題:

... 
    #Set the value within a 3x3 window to their "new_value" 
    for elem in Converted[istart:istop, jstart:jstop]: 

     Converted[elem] = elem + (elem * (value * ((Change[1]/100)) 

    #Set the main value to the new value 
    Converted[i,j] = value + (value * ((Change[0])/100)) 
    ... 

首先,當您迭代它時,elem的值不是索引!你不能用你得到的值爲數組索引,否則你會試圖通過0.01,pi之類的東西來索引它,或者甚至可能使用像5.6 + 98.44j這樣的複數。其次,你使用numpy是有原因的......沒有理由像這樣迭代每個元素。第三,你要兩次改變中心值,這幾乎不是你想要的。相反,我們可以做這樣的:

... 
    #--Set the value within a 3x3 window to their "new_value" 
    # Save the "center" value for later use 
    center = Converted[i,j] 

    # Adjust the pixels around the center by a percentage 
    Converted[istart:istop] *= 1 + Change[1]/100.0 

    # Adjust the center pixel by a different percentage 
    Converted[i,j] = center * (1 + Change[0]/100.0) 
    ... 

最後,你有名單「array」你正在傳遞的長度問題...

a = [16,2,20,4,14,6,70,8,9,100,32,15,7,14,50,20,17,10,9,20,7,17,50,2,19,20,21,22,23,24,25] 

這是一個31元數組......沒有截斷或添加數值的情況下,無法制作該方塊。您當前的代碼會嘗試將其轉換爲15x15陣列,這會導致錯誤(15x15矩陣需要255個值,(15**2))。我會假設你想要一個25個元素的5x5陣列。讓我們來替換成:

a = [16,2,20,4,14,6,70,8,9,100,32,15,7,14,50,20,17,10,9,20,7,17,50,2,19] 

好了,讓我們把所有這些建議彙集成一個可行的一段代碼:

import numpy as np 

def grid(array,samples,details): 
    array = np.asarray(array, dtype=np.float) 

    #Sides of the square (will be using a squarable number 
    Width = int(np.sqrt(array.size)) 
    #Convert to grid 
    Converted = array.reshape(Width,Width) 
    #Conversion details 
    Change = details[1:3] 
    nrows, ncols = Converted.shape 

    for value in samples: 

     #First instance where indexing returns it 
     i,j = np.argwhere(Converted == value)[0] 

     #Prevent indexing outside the boudaries of the 
     #array which would cause a "wraparound" assignment 
     istart, istop = max(i-1, 0), min(i+2, nrows) 
     jstart, jstop = max(j-1, 0), min(j+2, ncols) 


     #Set the value within a 3x3 window to their "new_value" 
     center_value = Converted[i,j] 
     Converted[istart:istop, jstart:jstop] *= 1 + Change[1]/100.0 
     Converted[i,j] = center_value * (1 + Change[0]/100.0) 

    #Convert back to 1D list 
    Converted.tolist() 

    return Converted 

a = [16,2,20,4,14,6,70,8,9,100,32,15,7,14,50,20,17,10,9,20,7,17,50,2,19] 
samples = [2, 7] 
grid_details = [10,50,100] 

result = grid(a,samples,grid_details) 

print(result) 

所以,這將您的原始數組:

[[ 16. 2. 20. 4. 14.] 
[ 6. 70. 8. 9. 100.] 
[ 32. 15. 7. 14. 50.] 
[ 20. 17. 10. 9. 20.] 
[ 7. 17. 50. 2. 19.]] 

進入:

[[ 32.  3. 40.  4. 14. ] 
[ 12. 280. 32. 18. 100. ] 
[ 32. 30. 10.5 28. 50. ] 
[ 20. 34. 20. 18. 20. ] 
[ 7. 17. 50.  2. 19. ]] 

好吧。現在我想你最初要問的是......在這種情況下,第二行,第二列中的項目被修改兩次......一次由於第一行,第二列中的2和一次由於7在第三行,第三列。

這是你想要避免?如果是這樣,你想在這種情況下發生什麼?

你想讓它只被第一場比賽修改嗎?第二場比賽?修改兩次,但只有修改百分比的總和?你需要定義你想要發生的事情。

無論如何,希望有所幫助!

編輯

如果你想避免匹配新修改的值,你可以找到所有的比賽開始修改以前的事情。舉例來說,如果我們改變這一部分:

for value in samples: 
    #First instance where indexing returns it 
    i,j = np.argwhere(Converted == value)[0] 

要這樣:

locations = [np.argwhere(Converted == value)[0] for value in samples] 
for i,j in locations: 
    ... 

應該做你想要什麼。希望這是明確的!

+0

首先感謝您的支持!我的意思是,現在修改後的值與以後的樣本值不匹配。即2增加100%爲4,然後樣本列表中的下一個值是4.我是否需要創建某種(i,j)位置的保留列表,這些位置被修改,以便如果找到的第一個值是一個以前修改過的值,它會繼續? – jimy 2011-02-04 05:05:14