目标是将一维阵列视为二维网格。第二个1D数组给出了需要在网格中更改的值列表,第三个数组表示了多少。
问题是修改后的值也会改变。
以下示例保留为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)
修改
根据你的回答Joe,我创建了一个版本,它按特定的%修改主值(中心),并用另一个修改周围的元素。但是,如何确保在下一次采样迭代期间不会再次转换更改的值。
感谢您的时间!
示例代码:
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:我不想避免修改之前修改过的网格中的任何值,无论是主要值还是周围值。
答案 0 :(得分:2)
您没有指定必须以任何特定方式执行此操作,因此我假设您对建议持开放态度。 完全不同的(和IMHO更简单)方法是创建一个数组数组:
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
*如果这是作业,你应该按照答案中指定的方式进行,那么你可能无法使用这个答案。
答案 1 :(得分:2)
首先,我不太确定你在问什么,所以请原谅我,如果我完全误解了你的问题......
您说您只想修改等于给定值的第一个项目,而不是修改所有项目。如果是这样,您将需要在找到第一个值后添加break
,否则您将继续循环并修改所有其他值。
然而,有更好的方法可以做你想做的事。
另外,你在顶部导入numpy然后从不(?)使用它......
这正是你想要使用numpy的那种东西,所以我将给出一个使用它的例子。
看起来您只是将一个函数应用于2D数组的3x3移动窗口,其中数组的值与某个给定值匹配。
如果我们想将给定索引周围的3x3区域设置为某个值,我们只需执行以下操作:
x[i-1:i+1, j-1:j+1] = value
... x
是您的数组,i
和j
是行和列,value
是您要将其设置为的值。 (类似地,x[i-1:i+1, j-1:j+1]
返回<i,j>
)
此外,如果我们想知道<i,j>
指示数组中特定值的位置,我们可以使用numpy.argwhere
,它会返回每个地方的<i,j>
指示列表给定条件为真的地方。
(在numpy数组上使用条件会产生一个布尔数组,显示条件为true或false的位置。因此,x >= 10
将生成一个与x
形状相同的布尔数组,不能只是True
或False
。这可以让您执行x[x>100] = 10
之类的好处,将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维数组和一个”平面“列表”。从某种意义上说,numpy数组已经存在。
例如:
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
此处,y
是x
的“视图”。如果我们更改y
的元素,我们会更改x
的相应元素,反之亦然。
同样,如果我们想要将一个2D数组(或3D,4D等)视为“平面”1D数组,您只需调用flat_array = y.ravel()
y
就是您的2D阵列。
希望无论如何都有帮助!