Python 3.1网格模拟问题

时间:2011-02-04 03:35:52

标签: python numpy python-3.x

基于答案from this question,我从一维数组创建了一个网格,它修改了一个值及其周围的邻居;如果在另一个数组中找到该值。主要值由特定的%转换,周围的元素由另一个转换。

但是,如何确保在下一次样本迭代期间不会再次转换更改的值。

以下示例代码。谢谢你的时间!

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)

1 个答案:

答案 0 :(得分:3)

首先,让我们逐节介绍您的代码......您现在所写的内容有几个问题......

顺便提一下,python中有一个松散的约定,为类保留大写和CamelCased名称。 (您经常会看到foo = FooBar(baz)之类的代码,其中foo是类FooBar的一个实例。)调用变量Converted代替{{1}没有错但是,你会看到的大多数代码都会使用后一种形式。

让我们从这里开始:

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)
    ...

你有数学问题!!一个2x2阵列作为4个元素,一个3x3阵列有9个,一个4x4阵列将有16个,依此类推......如果你想将一个序列重塑为一个正方形网格,你需要取平方根,而不是除以2 !让我们改为:

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

<击> 归咎于睡眠不足......显然, ... #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)) ... 而不是索引!您无法使用您获得的值对数组建立索引,否则您将尝试使用elem0.01之类的内容对其进行索引,甚至可能使用pi等复杂数字对其进行索引。其次,你使用numpy是有原因的...没有理由迭代这样的每个元素。第三,你将中心值改变两次,这几乎绝对不是你想要的。相反,我们可以这样做:

5.6 + 98.44j

最后,您传递的列表“ ... #--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

这是一个31元素的数组......如果没有截断或添加值,就没有办法制作那个正方形。您当前的代码会尝试将其转换为15x15数组,这会导致错误(15x15矩阵需要255个值,(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] ))。我假设您想要一个25个元素的5x5阵列。让我们用:替换它:

15**2

好的,让我们把所有这些建议放在一个可行的代码中:

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.]]

好。现在我认为你原来要问的是......在这种情况下,第二行中的项目,第二列被修改两次......一旦由于第一行中的2,第二列,以及一次由于7在第三行,第三列。

这是你想要避免的吗?如果是这样,在这种情况下你想发生什么?

你想让它只被第一场比赛修改吗?第二场比赛?修改了两次,但只是按百分比的总和进行了修改?你需要定义你想要发生的事情。

无论如何,希望有所帮助!

修改

如果您想避免匹配新修改的值,您可以在开始修改之前找到所有匹配项。例如,如果我们更改此部分:

[[  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. ]]

对此:

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

它应该做你想要的。希望很清楚!