在 python numpy 矩阵中迭代 - 添加和减去单元格元素出错
Iterating in a python numpy matrix - adding and subtracting to cell elements gone wrong
输入是一个 numpy 矩阵,过程是找到矩阵中大于 3 的所有条目。当程序找到值为 4 或更高的条目时,程序必须从该矩阵位置减去 4 并将该 4 分配 - 一个到上面的单元格,一个到下面的单元格,一个到左边的单元格,一个到右边的单元格。
输入是 [ [3,3,3], [3,4,3], [3,3,3] ],我期望输出 [ [3,4,3], [4 ,0,4], [3,4,3] ].
相反,我得到 [ [3,4,4], [4,2,1], [4,1,1] ]
需要将输入矩阵中间的4取出来,重新分配给矩阵的相邻单元格元素;一个在上面,一个在下面,一个在左边,一个在右边。
这不会发生。我无法理解它。任何人,请。
我添加了一些约束 - 这样如果矩阵中的条目在矩阵边界附近确实有一个 4 或更大的条目 - 这将确保您只向矩阵中的现有条目添加一个。
import numpy as np
dimension = 3
abba = np.matrix( [ [3,3,3], [3,4,3], [3,3,3] ] )
# implement the rules
def sandpile(field):
for x in range(dimension):
for y in range (dimension):
if field[x,y] > 3:
field[x,y] = field[x,y] - 4
if x+1 < dimension:
field[x+1,y] = field[x+1,y] + 1
if x-1 >= 0:
field[x-1,y] = field[x-1,y] + 1
if y-1 >= 0:
field[x,y-1] = field[x,y-1] + 1
if y+1 < dimension:
field[x,y+1] = field[x,y+1] + 1
return (field)
print(abba)
abba = sandpile(abba)
print(abba)
这是一个使用 np.where
并假设周期性边界的实现。如果你想从矩阵中添加 'leak' ,你必须相应地过滤掉右、左、上、下条件。
import numpy as np
dimx, dimy = 3, 3
a = np.random.randint(0, 5, (dimx, dimy))
greater3 = np.where(a > 3)
print(a)
left = (greater3[0], greater3[1]-1)
right = (greater3[0], (greater3[1]-1) % dimy)
top = (greater3[0] - 1, greater3[1])
bottom = ((greater3[1]-1) % dimx, greater3[1])
a[greater3] -= 4
a[left] += 1
a[right] += 1
a[top] += 1
a[bottom] += 1
print(a)
对现有代码稍作改动的方法之一:
import numpy as np
dimension = 3
abba = np.array( [ [3,3,3], [3,4,3], [3,3,3] ] )
done = False
for i in range(dimension):
for j in range(dimension):
if (abba[i][j]) >= 4:
abba[i][j] -= 4
if i>0:
abba[i-1][j] += 1
if i<dimension-1:
abba[i+1][j] += 1
if j>0:
abba[i][j-1] += 1
if j<dimension-1:
abba[i][j+1] += 1
done = True
break
if done:
break
print (abba)
输出:
[[3 4 3]
[4 0 4]
[3 4 3]]
输入是一个 numpy 矩阵,过程是找到矩阵中大于 3 的所有条目。当程序找到值为 4 或更高的条目时,程序必须从该矩阵位置减去 4 并将该 4 分配 - 一个到上面的单元格,一个到下面的单元格,一个到左边的单元格,一个到右边的单元格。
输入是 [ [3,3,3], [3,4,3], [3,3,3] ],我期望输出 [ [3,4,3], [4 ,0,4], [3,4,3] ].
相反,我得到 [ [3,4,4], [4,2,1], [4,1,1] ]
需要将输入矩阵中间的4取出来,重新分配给矩阵的相邻单元格元素;一个在上面,一个在下面,一个在左边,一个在右边。 这不会发生。我无法理解它。任何人,请。
我添加了一些约束 - 这样如果矩阵中的条目在矩阵边界附近确实有一个 4 或更大的条目 - 这将确保您只向矩阵中的现有条目添加一个。
import numpy as np
dimension = 3
abba = np.matrix( [ [3,3,3], [3,4,3], [3,3,3] ] )
# implement the rules
def sandpile(field):
for x in range(dimension):
for y in range (dimension):
if field[x,y] > 3:
field[x,y] = field[x,y] - 4
if x+1 < dimension:
field[x+1,y] = field[x+1,y] + 1
if x-1 >= 0:
field[x-1,y] = field[x-1,y] + 1
if y-1 >= 0:
field[x,y-1] = field[x,y-1] + 1
if y+1 < dimension:
field[x,y+1] = field[x,y+1] + 1
return (field)
print(abba)
abba = sandpile(abba)
print(abba)
这是一个使用 np.where
并假设周期性边界的实现。如果你想从矩阵中添加 'leak' ,你必须相应地过滤掉右、左、上、下条件。
import numpy as np
dimx, dimy = 3, 3
a = np.random.randint(0, 5, (dimx, dimy))
greater3 = np.where(a > 3)
print(a)
left = (greater3[0], greater3[1]-1)
right = (greater3[0], (greater3[1]-1) % dimy)
top = (greater3[0] - 1, greater3[1])
bottom = ((greater3[1]-1) % dimx, greater3[1])
a[greater3] -= 4
a[left] += 1
a[right] += 1
a[top] += 1
a[bottom] += 1
print(a)
对现有代码稍作改动的方法之一:
import numpy as np
dimension = 3
abba = np.array( [ [3,3,3], [3,4,3], [3,3,3] ] )
done = False
for i in range(dimension):
for j in range(dimension):
if (abba[i][j]) >= 4:
abba[i][j] -= 4
if i>0:
abba[i-1][j] += 1
if i<dimension-1:
abba[i+1][j] += 1
if j>0:
abba[i][j-1] += 1
if j<dimension-1:
abba[i][j+1] += 1
done = True
break
if done:
break
print (abba)
输出:
[[3 4 3]
[4 0 4]
[3 4 3]]