我有一个只有1和0的2D列表:
Boundaries = [
[0,0,0,0,0],
[0,1,1,1,0],
[0,1,1,1,1],
[0,1,1,1,0],
[0,0,1,0,0]]
我需要测试此列表以检查是否有任何1被1个其他1包围(例如此列表中的中间1)。如果有一个被1包围的1作为邻居,那么它应该被改为0,这样在运行程序之后,上面的列表将返回如下:
[
[0,0,0,0,0],
[0,1,1,1,0],
[0,1,0,1,1],
[0,1,1,1,0],
[0,0,1,0,0]]
我试图只使用一个参数(1' s和0' s的矩阵)。出于某种原因,这是一个非常困难的事情。到目前为止,我的代码看起来像这样:
def tempBoundaries(matrixC):
for i in matrixC:
for j in i:
if j == 1:
try:
if matrixC[i-1]==1 or matrixC[i+1]==1:
.......
无论出于何种原因,这是一场真正的斗争,我似乎无法弄清楚该做什么,任何提示或帮助将不胜感激!感谢。
答案 0 :(得分:10)
使用scipy,您可以执行以下操作
import numpy
boundaries = numpy.array([
[0,0,0,0,0],
[0,1,1,1,0],
[0,1,1,1,1],
[0,1,1,1,0],
[0,0,1,0,0]])
counts = scipy.signal.convolve2d(boundaries, numpy.ones((3,3)), mode='same')
# which gives you a matrix with counts of the number of 1s around each point
array([[ 1., 2., 3., 2., 1.],
[ 2., 4., 6., 5., 3.],
[ 3., 6., 9., 7., 4.],
[ 2., 5., 7., 6., 3.],
[ 1., 3., 4., 3., 1.]])
# so then you just find the points where it's == 9
counts == 9
array([[False, False, False, False, False],
[False, False, False, False, False],
[False, False, True, False, False],
[False, False, False, False, False],
[False, False, False, False, False]], dtype=bool)
# so you can update those positions
boundaries[counts == 9] = 0
所以整个操作很简单:
boundaries = numpy.array(Boundaries)
counts = scipy.signal.convolve2d(boundaries, numpy.ones((3,3)), mode='same')
boundaries[counts == 9] = 0
答案 1 :(得分:3)
由于后来添加了n numpy的要求,我觉得我应该添加一个纯粹的python答案。
你可以翻转算法。这个答案的灵感来自于计算机视觉特征提取中使用的霍夫变换(http://en.wikipedia.org/wiki/Hough_transform)。你不是在一个位置上狩猎,而是让位置投票支持他们所影响的事物。在你的情况下,每个有一个1的位置为自己及其所有邻居投票。
这是一种不同的方法,但它简化了围绕数据边缘的逻辑。你可以忽略这个方面,因为即使例如(-1,0)被投票,它也不会得到足够的投票来考虑。
更改以便单元格不为自己投票。这允许我们在其他情况下使用它(通过搜索具有8票的单元格)。我将其拆分为一个函数,该函数查找被1包围的所有单元格以及执行翻转的操作(取决于您正在搜索的内容)。
import collections
import itertools
def neighbours_of(i, j):
"""Positions of neighbours (includes out of bounds but excludes cell itself)."""
neighbours = list(itertools.product(range(i-1, i+2), range(j-1, j+2)))
neighbours.remove((i, j))
return neighbours
def find_surrounded(grid):
"""List of x,y positions in grid where the cell is surrounded by 1s."""
votes = collections.defaultdict(int)
for i, x in enumerate(grid):
for j, y in enumerate(x):
# we don't get to vote if not ...
if y == 0:
continue
# vote for everyone in the 3x3 square around us
for a, b in neighbours_of(i, j):
votes[(a, b)] += 1
# now the things we want to change are those that got 8 votes
surrounded_positions = [pos for pos, count in votes.items() if count == 8]
return surrounded_positions
def change_when_cell_type_surrounded(grid, cell_type):
"""Update grid inline to flip bits of cells of cell_type that are surrounded."""
# we'll flip to the opposite of what we're looking for
change_to = 1 - cell_type
surrounded = find_surrounded(grid)
for i, j in surrounded:
if grid[i][j] == cell_type:
grid[i][j] = change_to
grid = [[0,0,0,0,0],
[0,1,1,1,0],
[0,1,1,1,1],
[0,1,1,1,0],
[0,0,1,0,0]]
change_when_cell_type_surrounded(grid, 1)
change_when_cell_type_surrounded(grid, 0)
答案 2 :(得分:2)
要简化代码,您应该移动代码以检查函数内的邻居。您还可以使用路线列表,然后遍历指示,如下所示:
directions = [(-1, -1), (0, -1), ...]
def check_neighbors(m, x, y):
for direction in directions:
dx, dy = direction
# You should check here that (x+dx, y+dx)
# is still inside the matrix
if ...:
continue
if matrix[x+dx][y+dy] == 0:
return False
return True
在主函数中,矩阵基本上是一个列表列表。由于您要操作索引,因此应使用range
个可能的索引。
# Big assumption: all sublists have the same length
for x in range(len(matrixC)):
for y in range(len(matrixC[0])):
if check_neighbors(matrixC, x, y):
# Do what you want here
...
答案 3 :(得分:1)
怎么样:
Boundaries = [
[0,0,0,0,0],
[0,1,1,1,0],
[0,1,1,1,1],
[0,1,1,1,0],
[0,0,1,0,0]]
tochange = []
for i in xrange(len(Boundaries)-3):
for j in xrange(len(Boundaries)-3):
for k in xrange(3):
for l in xrange(3):
if not Boundaries[i+k][j+k]:
break
else:
continue
break
else:
tochange.append((i+1, j+1))
for i, j in tochange:
Boundaries[i][j] = 0
答案 4 :(得分:0)
您可以使用numpy
from numpy import ones
from scipy.signal import convolve2d
kernel = ones((3, 3))
#you create a matrix like this
#1 1 1
#1 1 1
#1 1 1
image = array(Boundaries)
#your boundaries were converted to a bidimensional numpy array
convolved = convolve2d(image, kernel, mode="same")
#you will have an image like this:
#[
# [1,2,3,2,1],
# [2,4,6,4,3],
# [3,6,9,7,4],
# [2,4,6,4,3],
# [1,2,3,2,1]
#]
然后你应该相应地改变图像:
for (x,y), value in numpy.ndenumerate(a):
image[x, y] = image[x, y] if convolved[x, y] < 9 else 0
免责声明:此代码不会在边框中杀死1。你必须相应地改变它
答案 5 :(得分:0)
没有numpy
修改强>
我认为这是一个更好的解决方案,因为它一旦邻居就打破了内循环 等于零
def zero_one(input2d, r, c):
for rr in (r-1, r, r+1):
for cc in (c-1, c, c+1):
if input2d[rr][cc] == 0 : return 1
return 0
Boundaries = [[0,0,0,0,0],
[0,1,1,1,0],
[0,1,1,1,1],
[0,1,1,1,0],
[0,0,1,0,0]]
rows = 5
cols = 5
Output = []
for r in range(rows):
Output.append([])
for c in range(cols):
if (r==0 or r==rows-1) or (c==0 or c==cols-1):
Output[r].append(Boundaries[r][c])
elif Boundaries[r][c] == 0:
Output[r].append(0)
else:
Output[r].append(zero_one(Boundaries, r, c))
for line in Output:
print line
执行上面的代码给出了
[0, 0, 0, 0, 0]
[0, 1, 1, 1, 0]
[0, 1, 0, 1, 1]
[0, 1, 1, 1, 0]
[0, 0, 1, 0, 0]
我以前的代码是在
之后编辑结束
In [15]: Boundaries = [
[0,0,0,0,0],
[0,1,1,1,0],
[0,1,1,1,1],
[0,1,1,1,0],
[0,0,1,0,0]]
In [16]: Output = [
[0,0,0,0,0],
[0,1,1,1,0],
[0,1,1,1,1],
[0,1,1,1,0],
[0,0,1,0,0]]
In [17]: for i in (1, 2, 3):
for j in (1,2,3):
s = 0
for m in (i-1, i, i+1):
for n in (j-1, j, j+1):
s = s+Boundaries[n][m]
if s == 9 : Output[j][i] = 0
....:
In [18]: Output
Out[18]:
[[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 1, 0, 1, 1],
[0, 1, 1, 1, 0],
[0, 0, 1, 0, 0]]
In [19]:
答案 6 :(得分:0)
我创建了一个像这样的简单商品,您可以自定义
from itertools import product, starmap, islice
def findNeighbors(grid, x, y):
xi = (0, -1, 1) if 0 < x < len(grid) - 1 else ((0, -1) if x > 0 else (0, 1))
yi = (0, -1, 1) if 0 < y < len(grid[0]) - 1 else ((0, -1) if y > 0 else (0, 1))
return islice(starmap((lambda a, b: grid[x + a][y + b]), product(xi, yi)), 1, None)
第一个示例:
grid = [[ 0, 1, 2, 3],
... [ 4, 5, 6, 7],
... [ 8, 9, 10, 11],
... [12, 13, 14, 15]]
n = list(findNeighbors(grid, 2, 1)) # find neighbors of 9
print(n)
输出: [8、10、5、4、6、13、12、14]
第二个示例:
grid = [[ 0, 1, 2, 3],
... [ 4, 5, 6, 7],
... [ 8, 9, 10, 11],
... [12, 13, 14, 15]]
n1 = list(findNeighbors(grid, 3, 3)) # find neighbors of 15
print(n1)
输出: [14,11,10]
让我知道您是否有任何疑问