如何检查数组数组中的边界重复项
How to check bordering duplicates in an array of arrays
如果我有一个由包含整数的数组组成的数组
arr[0] = [0, 0, 1, 1, 1, 0, -1] 0
arr[1] = [1, 0, 0, 0, 1, -1, 0] 1
arr[2] = [0, 0, 0, 1, 1, -1, 0] 2
0 1 2 3 4 5 6
例如,我想检查有多少相同的整数在水平和垂直方向上彼此相邻。例如,如果我选择坐标 (1, 2),这是一个 0。我希望它输出数字 8。因为有 8 个连续的零,所有零都彼此相邻。
我怎样才能编写一个函数来完全做到这一点?
我在Python
中尝试了以下两个功能
print checkLoc(1, 2)
def checkLoc(x, y):
amt = 0
n = arr[y][x]
checkPos(x, y, n)
return amt
def checkPos(x, y, n):
amt += 1
if arr[y - 1][x] == n:
checkPos(x, y - 1, n)
if arr[y + 1][x] == n:
checkPos(x, y + 1, n)
if arr[y][x - 1] == n:
checkPos(x - 1, y, n)
if arr[y][x + 1] == n:
checkPos(x + 1, y, n)
我希望这会起作用,但它不起作用。我已经对此进行了一些试验,由于我根本无法弄清楚,因此我将不胜感激。
谢谢
在您的递归方法中,您缺少基本情况并且未能防止下标超出范围。您也没有采取任何措施来阻止多次访问同一职位。以下实现了您似乎试图使用的逻辑,借助于帮助数据结构来跟踪访问了哪些位置。请注意,我将 arr
设为局部变量,因为我不喜欢在没有充分理由的情况下使用全局变量:
def checkPos(arr,visited,i,j,v):
visited[i][j] = True
if arr[i][j] != v:
return 0
else:
count = 1 #current position
if i > 0 and not visited[i-1][j]:
count += checkPos(arr,visited,i-1,j,v)
if i < len(arr)-1 and not visited[i+1][j]:
count += checkPos(arr,visited,i+1,j,v)
if j > 0 and not visited[i][j-1]:
count += checkPos(arr,visited,i,j-1,v)
if j < len(arr[0])-1 and not visited[i][j+1]:
count += checkPos(arr,visited,i,j+1,v)
return count
def checkLoc(arr, x, y):
m = len(arr) # number of rows
n = len(arr[0]) #number of columns
visited = [[False]*n for _ in range(m)]
v = arr[y][x] #value at the position
return checkPos(arr, visited, y, x, v)
#test:
arr =[[0, 0, 1, 1, 1, 0, -1],
[1, 0, 0, 0, 1, -1, 0],
[0, 0, 0, 1, 1, -1, 0]]
counts = [[checkLoc(arr,j,i) for j in range(7)] for i in range(3)]
print('\n'.join(str(row) for row in counts))
输出符合预期:
[8, 8, 6, 6, 6, 1, 1]
[1, 8, 8, 8, 6, 2, 2]
[8, 8, 8, 6, 6, 2, 2]
您尝试做的事情可以使用 flood-fill 算法来解决。考虑你的数组。
arr = np.array([[0, 0, 1, 1, 1, 0, -1],
[1, 0, 0, 0, 1, -1, 0],
[0, 0, 0, 1, 1, -1, 0]])
还有一个flood-fill算法,例如
def fillin(arr, x, y, new_value):
"""Graphically fills in `new_value` on location (x, y) replacing all
adjacent values currently located there."""
old_value = arr[y, x]
n, m = arr.shape
arr[y, x] = new_value
if y > 0 and arr[y-1, x] == old_value:
fillin(arr, x, y-1, new_value)
if y < n-1 and arr[y+1, x] == old_value:
fillin(arr, x, y+1, new_value)
if x > 0 and arr[y, x-1] == old_value:
fillin(arr, x-1, y, new_value)
if x < m-1 and arr[y, x+1] == old_value:
fillin(arr, x+1, y, new_value)
那么这个算法的作用很简单,例如用其他东西填充 (1, 2) 处的相邻零点
>>> fillin(arr, 1, 2, 2)
>>> arr
array([[ 2, 2, 1, 1, 1, 0, -1],
[ 1, 2, 2, 2, 1, -1, 0],
[ 2, 2, 2, 1, 1, -1, 0]])
利用它解决您的问题对您正在调查的单元格进行编码
(arr == arr[2, 1]).astype(int)
为您的选择提供 0-1 编码(这里 arr[2, 1] == 0
),然后减去填充前后数组的总和,得到每个位置的迭代相邻值的数量.让我们定义一种检查一个位置的方法(这也将注意不修改输入arr
)
def check(arr, x, y):
arr_coded = (arr == arr[y, x]).astype(int)
sum_before = arr_coded.sum()
fillin(arr_coded, x, y, 0)
return sum_before - arr_coded.sum()
在你的情况下它会给出
>>> check(arr, 1, 2)
8
还考虑定义一个方法来检查整个输入数组
def check_all(arr):
n, m = arr.shape
return np.reshape([check(arr, x, y) for y in range(n) for x in range(m)], (n, m))
这将 return 一个具有 "same iterative adjecent value counts"
的 矩阵
>>> check_all(arr)
array([[8, 8, 6, 6, 6, 1, 1],
[1, 8, 8, 8, 6, 2, 2],
[8, 8, 8, 6, 6, 2, 2]])
如果我有一个由包含整数的数组组成的数组
arr[0] = [0, 0, 1, 1, 1, 0, -1] 0
arr[1] = [1, 0, 0, 0, 1, -1, 0] 1
arr[2] = [0, 0, 0, 1, 1, -1, 0] 2
0 1 2 3 4 5 6
例如,我想检查有多少相同的整数在水平和垂直方向上彼此相邻。例如,如果我选择坐标 (1, 2),这是一个 0。我希望它输出数字 8。因为有 8 个连续的零,所有零都彼此相邻。 我怎样才能编写一个函数来完全做到这一点?
我在Python
中尝试了以下两个功能print checkLoc(1, 2)
def checkLoc(x, y):
amt = 0
n = arr[y][x]
checkPos(x, y, n)
return amt
def checkPos(x, y, n):
amt += 1
if arr[y - 1][x] == n:
checkPos(x, y - 1, n)
if arr[y + 1][x] == n:
checkPos(x, y + 1, n)
if arr[y][x - 1] == n:
checkPos(x - 1, y, n)
if arr[y][x + 1] == n:
checkPos(x + 1, y, n)
我希望这会起作用,但它不起作用。我已经对此进行了一些试验,由于我根本无法弄清楚,因此我将不胜感激。 谢谢
在您的递归方法中,您缺少基本情况并且未能防止下标超出范围。您也没有采取任何措施来阻止多次访问同一职位。以下实现了您似乎试图使用的逻辑,借助于帮助数据结构来跟踪访问了哪些位置。请注意,我将 arr
设为局部变量,因为我不喜欢在没有充分理由的情况下使用全局变量:
def checkPos(arr,visited,i,j,v):
visited[i][j] = True
if arr[i][j] != v:
return 0
else:
count = 1 #current position
if i > 0 and not visited[i-1][j]:
count += checkPos(arr,visited,i-1,j,v)
if i < len(arr)-1 and not visited[i+1][j]:
count += checkPos(arr,visited,i+1,j,v)
if j > 0 and not visited[i][j-1]:
count += checkPos(arr,visited,i,j-1,v)
if j < len(arr[0])-1 and not visited[i][j+1]:
count += checkPos(arr,visited,i,j+1,v)
return count
def checkLoc(arr, x, y):
m = len(arr) # number of rows
n = len(arr[0]) #number of columns
visited = [[False]*n for _ in range(m)]
v = arr[y][x] #value at the position
return checkPos(arr, visited, y, x, v)
#test:
arr =[[0, 0, 1, 1, 1, 0, -1],
[1, 0, 0, 0, 1, -1, 0],
[0, 0, 0, 1, 1, -1, 0]]
counts = [[checkLoc(arr,j,i) for j in range(7)] for i in range(3)]
print('\n'.join(str(row) for row in counts))
输出符合预期:
[8, 8, 6, 6, 6, 1, 1]
[1, 8, 8, 8, 6, 2, 2]
[8, 8, 8, 6, 6, 2, 2]
您尝试做的事情可以使用 flood-fill 算法来解决。考虑你的数组。
arr = np.array([[0, 0, 1, 1, 1, 0, -1],
[1, 0, 0, 0, 1, -1, 0],
[0, 0, 0, 1, 1, -1, 0]])
还有一个flood-fill算法,例如
def fillin(arr, x, y, new_value):
"""Graphically fills in `new_value` on location (x, y) replacing all
adjacent values currently located there."""
old_value = arr[y, x]
n, m = arr.shape
arr[y, x] = new_value
if y > 0 and arr[y-1, x] == old_value:
fillin(arr, x, y-1, new_value)
if y < n-1 and arr[y+1, x] == old_value:
fillin(arr, x, y+1, new_value)
if x > 0 and arr[y, x-1] == old_value:
fillin(arr, x-1, y, new_value)
if x < m-1 and arr[y, x+1] == old_value:
fillin(arr, x+1, y, new_value)
那么这个算法的作用很简单,例如用其他东西填充 (1, 2) 处的相邻零点
>>> fillin(arr, 1, 2, 2)
>>> arr
array([[ 2, 2, 1, 1, 1, 0, -1],
[ 1, 2, 2, 2, 1, -1, 0],
[ 2, 2, 2, 1, 1, -1, 0]])
利用它解决您的问题对您正在调查的单元格进行编码
(arr == arr[2, 1]).astype(int)
为您的选择提供 0-1 编码(这里 arr[2, 1] == 0
),然后减去填充前后数组的总和,得到每个位置的迭代相邻值的数量.让我们定义一种检查一个位置的方法(这也将注意不修改输入arr
)
def check(arr, x, y):
arr_coded = (arr == arr[y, x]).astype(int)
sum_before = arr_coded.sum()
fillin(arr_coded, x, y, 0)
return sum_before - arr_coded.sum()
在你的情况下它会给出
>>> check(arr, 1, 2)
8
还考虑定义一个方法来检查整个输入数组
def check_all(arr):
n, m = arr.shape
return np.reshape([check(arr, x, y) for y in range(n) for x in range(m)], (n, m))
这将 return 一个具有 "same iterative adjecent value counts"
的 矩阵>>> check_all(arr)
array([[8, 8, 6, 6, 6, 1, 1],
[1, 8, 8, 8, 6, 2, 2],
[8, 8, 8, 6, 6, 2, 2]])