遍历并更新数组值直到满足条件,或者直到完成 100 次循环?
Looping through, and updating, array values until a condition is met, or until 100 loops have been completed?
在 Jupyter Notebook 上使用 Python 3.7。我正在开发一个将循环遍历 2D Numpy 数组("board",如果你愿意的话)的项目,检查数字 1 的所有实例。当它找到数字 1 时,我需要它检查值左边,右边,上面,下面。如果它旁边的任何值是 2,则该元素本身变为 2。
循环遍历整个数组后,我需要代码来检查电路板是否从该单个循环开始时发生了变化。如果它没有改变,那么模拟(循环)应该结束。但是,如果它发生了变化,那么模拟应该再次 运行。但是,模拟循环不应超过 100 圈。
这是导致我的问题单元格的设置:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import numpy.random as rand
import time
from IPython.display import display, clear_output
def set_board(height=5,width=10,density=.75):
city = np.zeros((height,width),dtype='int64')
for i in range(height):
for j in range(width):
if rand.random() <= density:
city[i,j] = 1
return city
def VisMap(Map=set_board(),Colors=plt.cm.RdYlGn):
MapVis = plt.imshow(Map, Colors)
return MapVis
def onBoard(i, j, array):
if (i >= 0 and i < array.shape[0]-1
and j >= 0 and j < array.shape[1]-1):
return True
return False
def getNeighborValues(i, j, board):
neighborhood_indices = [(i-1,j),(i,j-1),(i+1,j),(i,j+1)]
neighborhood_values = []
for index in neighborhood_indices:
if onBoard(index[0],index[1],board) == True:
neighborhood_values.append(board[index[0],index[1]])
pass
return neighborhood_values
def startRumor(board):
height, width = board.shape
height_quarters = int(height/4)
width_quarters = int(width/4)
starting_middle_height_index = height_quarters
ending_middle_height_index = 3*height_quarters
starting_middle_width_index = width_quarters
ending_middle_width_index = 3*width_quarters
found_starting_point = False
if np.all(board[starting_middle_height_index:ending_middle_height_index, starting_middle_width_index:ending_middle_width_index] == 0):
i = rand.randint(starting_middle_height_index, ending_middle_height_index)
j = rand.randint(starting_middle_width_index, ending_middle_width_index)
board[i,j] = 2
found_starting_point = True
while not found_starting_point:
i = rand.randint(starting_middle_height_index, ending_middle_height_index)
j = rand.randint(starting_middle_width_index, ending_middle_width_index)
if board[i,j] == 1:
found_starting_point = True
board[i, j] = 2
这是我遇到问题的单元格(特别是从第 5 步开始):
#Step 1: Initializing my board
StartingBoard = set_board(100,200,.4)
#Step 2: Visualizing my board
PreRumorVis = VisMap(StartingBoard)
#Step 3: Starting the rumor
startRumor(StartingBoard)
#Step 4: Visualizing the board after the rumor has started
PostRumorVis = VisMap(StartingBoard)
#Step 5: Create a copy of the city, and turn anything
#with a 2 around it into a 2, and keep doing that for 100
#loops. Or, if the city at the end of the loop is equal to
#the one from the beginning of the loop, break it. If there
#is some change, though, set the new city to now be the
#updated copy, and loop through again. (In this case, it
#probably should loop all 100 times).
City_Copy = StartingBoard.copy()
New_City = City_Copy.copy()
iterations = 0
for num in range(100):
for i in range(City_Copy.shape[0]):
for j in range(City_Copy.shape[1]):
if City_Copy[i,j] == 1:
if 2 in getNeighborValues(i,j, City_Copy):
New_City[i,j] = 2
else:
New_City[i,j] = 1
if np.array_equal(New_City, City_Copy) == True:
break
else:
City_Copy = New_City.copy()
iterations += 1
print("This rumor has been around for", iterations, "days.")
New_City
编辑:感谢其中一位评论者,我发现我一开始缺少复制功能。但是,我还有大约 18 天,应该是 100(或非常接近)。想知道我应该用 for 循环还是 while 循环打开。问题可能出在将变量设置为等于副本的地方……这让我有点困惑。这一切在逻辑上都是有道理的,但有一个地方松动了。
在 Python 中,赋值语句不复制对象,而是在目标和对象之间创建绑定。当我们使用 = 运算符时,用户认为这会创建一个新对象,但事实并非如此。它只创建一个共享原始对象引用的新变量。
例子:-
>>> a=np.array([[0,1],[0,2]])
>>> b=a
>>> np.array_equal(b,a)
True
>>> b[0][1]=1
>>> b
array([[0, 1],
[0, 2]])
>>> a
array([[0, 1],
[0, 2]])
>>> np.array_equal(b,a)
True
这是由于浅拷贝造成的。浅复制仅限于复合对象,例如 lists。 要避免这种情况,请进行深复制。
>>> import copy
>>> a=np.array([[0,1],[0,2]])
>>> b=copy.deepcopy(a)
>>> np.array_equal(b,a)
True
>>>b[0][0]=1
>>> np.array_equal(b,a)
False
解法:-
由于您已经分配了 New_City=City_Copy,因此 New_City 中的任何更改都会反映在 City_Copy. 中因此它们都是相等的,循环第一次中断 itself.So 循环不递增。尝试使用deepcopy来解决这个问题。
参考:-
在 Jupyter Notebook 上使用 Python 3.7。我正在开发一个将循环遍历 2D Numpy 数组("board",如果你愿意的话)的项目,检查数字 1 的所有实例。当它找到数字 1 时,我需要它检查值左边,右边,上面,下面。如果它旁边的任何值是 2,则该元素本身变为 2。
循环遍历整个数组后,我需要代码来检查电路板是否从该单个循环开始时发生了变化。如果它没有改变,那么模拟(循环)应该结束。但是,如果它发生了变化,那么模拟应该再次 运行。但是,模拟循环不应超过 100 圈。
这是导致我的问题单元格的设置:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import numpy.random as rand
import time
from IPython.display import display, clear_output
def set_board(height=5,width=10,density=.75):
city = np.zeros((height,width),dtype='int64')
for i in range(height):
for j in range(width):
if rand.random() <= density:
city[i,j] = 1
return city
def VisMap(Map=set_board(),Colors=plt.cm.RdYlGn):
MapVis = plt.imshow(Map, Colors)
return MapVis
def onBoard(i, j, array):
if (i >= 0 and i < array.shape[0]-1
and j >= 0 and j < array.shape[1]-1):
return True
return False
def getNeighborValues(i, j, board):
neighborhood_indices = [(i-1,j),(i,j-1),(i+1,j),(i,j+1)]
neighborhood_values = []
for index in neighborhood_indices:
if onBoard(index[0],index[1],board) == True:
neighborhood_values.append(board[index[0],index[1]])
pass
return neighborhood_values
def startRumor(board):
height, width = board.shape
height_quarters = int(height/4)
width_quarters = int(width/4)
starting_middle_height_index = height_quarters
ending_middle_height_index = 3*height_quarters
starting_middle_width_index = width_quarters
ending_middle_width_index = 3*width_quarters
found_starting_point = False
if np.all(board[starting_middle_height_index:ending_middle_height_index, starting_middle_width_index:ending_middle_width_index] == 0):
i = rand.randint(starting_middle_height_index, ending_middle_height_index)
j = rand.randint(starting_middle_width_index, ending_middle_width_index)
board[i,j] = 2
found_starting_point = True
while not found_starting_point:
i = rand.randint(starting_middle_height_index, ending_middle_height_index)
j = rand.randint(starting_middle_width_index, ending_middle_width_index)
if board[i,j] == 1:
found_starting_point = True
board[i, j] = 2
这是我遇到问题的单元格(特别是从第 5 步开始):
#Step 1: Initializing my board
StartingBoard = set_board(100,200,.4)
#Step 2: Visualizing my board
PreRumorVis = VisMap(StartingBoard)
#Step 3: Starting the rumor
startRumor(StartingBoard)
#Step 4: Visualizing the board after the rumor has started
PostRumorVis = VisMap(StartingBoard)
#Step 5: Create a copy of the city, and turn anything
#with a 2 around it into a 2, and keep doing that for 100
#loops. Or, if the city at the end of the loop is equal to
#the one from the beginning of the loop, break it. If there
#is some change, though, set the new city to now be the
#updated copy, and loop through again. (In this case, it
#probably should loop all 100 times).
City_Copy = StartingBoard.copy()
New_City = City_Copy.copy()
iterations = 0
for num in range(100):
for i in range(City_Copy.shape[0]):
for j in range(City_Copy.shape[1]):
if City_Copy[i,j] == 1:
if 2 in getNeighborValues(i,j, City_Copy):
New_City[i,j] = 2
else:
New_City[i,j] = 1
if np.array_equal(New_City, City_Copy) == True:
break
else:
City_Copy = New_City.copy()
iterations += 1
print("This rumor has been around for", iterations, "days.")
New_City
编辑:感谢其中一位评论者,我发现我一开始缺少复制功能。但是,我还有大约 18 天,应该是 100(或非常接近)。想知道我应该用 for 循环还是 while 循环打开。问题可能出在将变量设置为等于副本的地方……这让我有点困惑。这一切在逻辑上都是有道理的,但有一个地方松动了。
在 Python 中,赋值语句不复制对象,而是在目标和对象之间创建绑定。当我们使用 = 运算符时,用户认为这会创建一个新对象,但事实并非如此。它只创建一个共享原始对象引用的新变量。
例子:-
>>> a=np.array([[0,1],[0,2]])
>>> b=a
>>> np.array_equal(b,a)
True
>>> b[0][1]=1
>>> b
array([[0, 1],
[0, 2]])
>>> a
array([[0, 1],
[0, 2]])
>>> np.array_equal(b,a)
True
这是由于浅拷贝造成的。浅复制仅限于复合对象,例如 lists。 要避免这种情况,请进行深复制。
>>> import copy
>>> a=np.array([[0,1],[0,2]])
>>> b=copy.deepcopy(a)
>>> np.array_equal(b,a)
True
>>>b[0][0]=1
>>> np.array_equal(b,a)
False
解法:-
由于您已经分配了 New_City=City_Copy,因此 New_City 中的任何更改都会反映在 City_Copy. 中因此它们都是相等的,循环第一次中断 itself.So 循环不递增。尝试使用deepcopy来解决这个问题。
参考:-