2011-02-02 12 views
1

目的は1次元配列を2次元グリッドとして扱うことです。 2番目の1D配列は、グリッド内で変更する必要がある値のリストを提供し、3番目の配列は、どれだけどれだけの値を示すかを示します。Python 3.1- Grid Simulation概念的な問題

修正された値を囲む値も変更されるということです。

以下の例は1D配列のままですが、2Dグリッドのように計算されます。できます;現在は、1Dリスト(サンプル)の値と一致するグリッド内のすべての値を変更します。私は1つの値とその周辺をリストの1つの値に対してのみ変換するのではなく、

つまり、リストが[2,3]の場合。私は、反復で渡される最初の2と3の値を変更したいだけです。今の例では、グリッド内の2つごとに変更されています。

私は混乱しています(おそらく私が修正計算を構成した方法のせいで)、グリッドを繰り返し処理して、一致するたびにリスト値を削除することはできません。

ありがとうございます!

コードは次のとおりです。

import numpy 

def grid_range(value): 
    if value > 60000: 
     value = 60000 
     return (value) 
    elif value < 100: 
     value = 100 
     return(value) 
    elif value <= 60000 and value >= 100: 
     return(value) 


def grid(array,samples,details): 

    original_length = len(array) 
    c = int((original_length)**0.5) 

    new_array = []                 #create a new array with the modified values 

    for elem in range (len(array)):             #if the value is in samples 
     if array[elem] in samples: 
      value = array[elem] + (array[elem] * (details[1]/100)) 
      test_range = grid_range(value) 
      new_array.append(test_range) 

     elif ((elem + 1) < original_length) and array[elem - 1] in samples:           #change the one before the value         
      if (len(new_array) % c == 0) and array[elem + 1] not in samples:        
       new_array.append(array[elem]) 
      else: 
       new_forward_element = array[elem] +(array[elem] * (details[2]/100)) 
       test_range1 = grid_range(new_forward_element) 
       new_array.append(test_range1) 

     elif ((elem + 1) < original_length) and (array[elem + 1]) in samples:  #change the one before and that it doesn't attempt to modify passed the end of the array         
      if (len(new_array) + 1) % c == 0: 
       new_array.append(array[elem]) 
      else: 
       new_back_element = array[elem] +(array[elem] * (details[2]/100)) 
       test_range2 = grid_range(new_back_element)  
       new_array.append(test_range2) 

     elif ((elem+c) <= (original_length - c))and(array[elem + c]) in samples: #if based on the 9 numbers on the right of the keyboard with test value numebr 5; this is position '2' 
      extra1 = array[elem] +(array[elem] * (details[2]/100)) 
      test_range3 = grid_range(extra1) 
      new_array.append(test_range3) 

     elif (array[abs(elem - c)]) in samples:          #position '8' 
      extra2 = array[elem] +(array[elem] * (details[2]/100)) 
      test_range4 = grid_range(extra2) 
      new_array.append(test_range4) 

     elif (array[abs(elem - (c-1))]) in samples:         #position '7' 
      if (elem - (c-1)) % c == 0: 
       new_array.append(array[elem]) 
      else: 
       extra3 = array[elem] +(array[elem] * (details[2]/100)) 
       test_range5 = grid_range(extra3) 
       new_array.append(test_range5) 

     elif (array[abs(elem - (c+1))]) in samples:         #position '9'  
      if (elem - (c+1) + 1) % c == 0: 
       new_array.append(array[elem]) 

      else: 
       extra4 = array[elem] +(array[elem] * (details[2]/100)) 
       test_range6 = grid_range(extra4) 
       new_array.append(test_range6) 

     elif ((elem +(c-1)) < original_length) and (array[elem + (c-1)]) in samples: #position '1', also not passed total array length 
      if (elem + (c-1)+ 1) % c == 0: 
       new_array.append(array[elem]) 
      else:    
       extra5 = array[elem] +(array[elem] * (details[2]/100)) 
       test_range7 = grid_range(extra5) 
       new_array.append(test_range7) 

     elif (elem + (c+1)) < (len(array)- c) and (array[elem + (c+1)]) in samples:  #position '3', also not passed total array length 
      if (elem + (c+1)) % c == 0: 
       new_array.append(array[elem]) 
      else: 
       extra6 = array[elem] +(array[elem] * (details[2]/100)) 
       test_range8 = grid_range(extra6) 
       new_array.append(test_range8) 

     else: 
      new_array.append(array[elem]) 

    return(new_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] 
samples = [2] 
grid_details = [10,50,100] 

result = grid(a,samples,grid_details) 

EDIT:

あなたの答えジョーに基づいて、私は特定の%で、メイン値(中央)を変更し、別のことで、周囲の要素のバージョンを作成しました。ただし、変更された値がサンプルの次の反復中に再び変換されないようにするにはどうすればよいですか。

ありがとうございました!

例コード:

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) 

print(result) 

PS:私はそれが主値または周囲の値でも、以前に変更されているグリッド内の任意の値を変更することを避けるためにwan't。

答えて

2

まず、あなたが何を求めているのかよくわからないので、私があなたの質問を完全に誤解した場合、私を許してください...

あなたは、指定された値に等しく、それらのすべてではない最初のアイテムだけを修正したいと言います。その場合は、最初の値を見つけた後にbreakを追加する必要があります。そうしないと、他のすべての値をループして変更します。

しかし、あなたが望むことを行うためのより良い方法があります。あなたが一番上にnumpyのをインポートしないと、その後決してしている(?)、それを使用して

はまた、...

これはまさにあなたがnumpyのを使用したいと思いますものの一種であるので、私は行きますよそれを使用する例を挙げてください。

2次元配列の3x3移動ウィンドウに関数を適用するだけです。ここでは、配列の値が特定の値と一致します。

我々はいくつかの値に指定されたインデックスを中心に3×3のエリアを設定したい場合は、私達はちょうどこのような何かしたい:xはあなたの配列であり、ijが行です

x[i-1:i+1, j-1:j+1] = value 

を...列には、valueが設定したい値です。我々が知りたい場合(同様に、<i,j>の周囲3×3アレイを返しx[i-1:i+1, j-1:j+1])さらに

<i,j>は、特定の値は、配列内で発生ここで、我々は<i,j>のリストは、各場所を示して返されたnumpy.argwhereを使用できることを示し与えられた条件が真である場合。

(条件が真であるか偽である場合を示すブール配列でnumpyのアレイ結果に条件文を使用しますので、x >= 10xと同じ形状のブール配列をもたらす、ない単にTrue又はFalse。これができ私は、このスニペットは、あなたが何をしたいのかないと信じて、それをすべてまとめると100

)10に超えるx内のすべての値を設定するx[x>100] = 10のような素敵なことを行う:

import numpy as np 

# First let's generate some data and set a few duplicate values 
data = np.arange(100).reshape(10,10) 
data[9,9] = 2 
data[8,6] = 53 

print 'Original Data:' 
print data 

# We want to replace the _first_ occurences of "samples" with the corresponding 
# value in "grid_details" within a 3x3 window... 
samples = [2, 53, 69] 
grid_details = [200,500,100] 

nrows, ncols = data.shape 
for value, new_value in zip(samples, grid_details): 
    # Notice that were're indexing the _first_ item than argwhere returns! 
    i,j = np.argwhere(data == value)[0] 

    # We need to make sure that we don't index outside the boundaries 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 be "new_value" 
    data[istart:istop, jstart:jstop] = new_value 

print 'Modified Data:' 
print data 

この利回り:

Original Data: 
[[ 0 1 2 3 4 5 6 7 8 9] 
[10 11 12 13 14 15 16 17 18 19] 
[20 21 22 23 24 25 26 27 28 29] 
[30 31 32 33 34 35 36 37 38 39] 
[40 41 42 43 44 45 46 47 48 49] 
[50 51 52 53 54 55 56 57 58 59] 
[60 61 62 63 64 65 66 67 68 69] 
[70 71 72 73 74 75 76 77 78 79] 
[80 81 82 83 84 85 50 87 88 89] 
[90 91 92 93 94 95 96 97 98 2]] 

Modified Data: 
[[ 0 200 200 200 4 5 6 7 8 9] 
[ 10 200 200 200 14 15 16 17 18 19] 
[ 20 21 22 23 24 25 26 27 28 29] 
[ 30 31 32 33 34 35 36 37 38 39] 
[ 40 41 500 500 500 45 46 47 48 49] 
[ 50 51 500 500 500 55 56 57 100 100] 
[ 60 61 500 500 500 65 66 67 100 100] 
[ 70 71 72 73 74 75 76 77 100 100] 
[ 80 81 82 83 84 85 50 87 88 89] 
[ 90 91 92 93 94 95 96 97 98 2]] 

は最後に、あなたがフラットな「リスト 『』 N次元配列との両方としてビュー何か」をしたいと述べました。これは、意味のある配列が既に何であるかにある。例えば

:ここ

import numpy as np 

x = np.arange(9) 
y = x.reshape(3,3) 

print x 
print y 

y[2,2] = 10000 

print x 
print y 

yxへの "ビュー" です。 yの要素を変更すると、xの対応する要素が変更され、その逆も同様です。

同様に、2D配列(3D、4Dなど)を「フラット」な1D配列として表示する場合は、flat_array = y.ravel()を呼び出すことができます。yは2D配列です。

希望すると、どんな速度でも役立ちます。

+0

これは、私が探していたものの素晴らしさです。御時間ありがとうございます! – jimy

+0

驚くばかり!ナンシーが何のために使われたのだろうと思っていた。 +1 – John

+0

私はこれに関連するもう一つの質問があります。下記を参照してください。 – jimy

2

あなたはそれを特定の方法で行う必要があるとは指定していないので、私はあなたが提案をすることができると仮定しています。 完全に異なる(及び私見簡単な)方法は、アレイのアレイにするために次のようになります単にのインデックス次に、リスト(行)の指標を供給する、グリッド上の場所にアクセスする

grid = [[0,0,0,0,0], 
     [0,0,0,2,0], 
     [1,0,0,0,0], 
     [0,0,0,0,0], 
     [0,0,3,0,0]] 

をそのグリッド上の位置(列)。たとえば、次のように

1 = grid[2][0] 
2 = grid[1][3] 
3 = grid[4][2] 

(例えば可変サイズの)非ハードコードグリッドを作成するには:

def gridder(width,height): 
    list = [] 
    sublist = [] 
    for i in range(0,width): 
     sublist.append(1) 
    for i in range(0,height): 
     list.append(sublist) 
    return list 

グリッドの一部を変更するには:

def modifier(x,y,value): 
    grid[y][x] = value 

*この場合は宿題であり、答えに指定された方法でそれを行うと仮定した場合、おそらくこの答えを使用することはできません。

+0

私の理解を助け、あなたのコメントと時間の両方に感謝します! – jimy

+0

@jimy:助けてくれたら、アップしてください。 – John

関連する問題