列出相邻的单元格

时间:2012-02-12 02:22:38

标签: python

我有一个带有id值的570 x 800矩阵。如果找到每个项目的相邻邻居,我想做什么。除非单元格沿边界,否则最大邻居数为8。在这种情况下,将有三个邻居。我想将邻居附加到列表中。当每个单元格都有x和y坐标时,我看到了用于查找邻居的帖子,这非常有用,但是如何在没有坐标的情况下修改代码。 ids以字符串形式出现,因为我将它用作字典中的键。任何帮助,将不胜感激。

3 个答案:

答案 0 :(得分:6)

假设你要做的是在矩阵上构造一个八连通网格,并且矩阵中项目的位置定义了x坐标和y坐标,你可以使用这样的东西:

def eight_connected_neighbours( xmax, ymax, x, y ):
    """The x- and y- components for a single cell in an eight connected grid

    Parameters
    ----------
    xmax : int
        The width of the grid

    ymax: int
        The height of the grid

    x : int
        The x- position of cell to find neighbours of

    y : int 
        The y- position of cell to find neighbours of

    Returns
    -------
    results : list of tuple
        A list of (x, y) indices for the neighbours    
    """
    results = []
    for dx in [-1,0,1]:
        for dy in [-1,0,1]:
            newx = x+dx
            newy = y+dy
            if (dx == 0 and dy == 0):
                continue
            if (newx>=0 and newx<xmax and newy >=0 and newy<ymax):
                results.append( (newx, newy) )
    return results

答案 1 :(得分:2)

让我给numpy提供一个替代答案,如果您正在对数据执行更重要的任务,那么您可能需要考虑这个库。此方法的优点是具有参数k的最近邻居数量的可扩展性。设置:

from numpy import *

k = 1

# Create the nearest neighbors
Xidx, Yidx = mgrid[-k:k+1,-k:k+1]

# Remove the center (0,0) index
center = (Xidx==0) & (Yidx==0)
Xidx = Xidx[~center]
Yidx = Yidx[~center]

现在,您可以使用A[Xidx+dx, Yidx+dy]访问最近的邻居,其中dxdyxy坐标的偏移量。

示例

我们采用随机矩阵:

A = random.random((5,5))
print A

对我而言:

[[ 0.90779297  0.91195651  0.32751438  0.44830373  0.2528675 ]
 [ 0.02542108  0.52542962  0.28203009  0.35606998  0.88076027]
 [ 0.08955781  0.98903843  0.86881875  0.21246095  0.92005691]
 [ 0.57253561  0.08830487  0.06418296  0.59632344  0.53604546]
 [ 0.7646322   0.50869651  0.00229266  0.26363367  0.64899637]]

现在我们可以用

查看最近的邻居
dx, dy = 2,1

print "Cell value A[%i,%i] = %f " % (dx, dy, A[dx,dy])
print "k=%i nearest neighbors: "%k, A[Xidx+dx, Yidx+dy]

,并提供:

Cell value A[2,1] = 0.989038 
k=1 nearest neighbors:  [ 0.02542108  0.52542962  0.28203009  0.08955781  0.86881875 0.57253561  0.08830487  0.06418296]

<强>加成

如前所述,通过更改k,您可以轻松获得下一个最近的邻居,以及下一个邻居等...此外,还可以索引更高阶的数组(比如等级3的张量) )现在可以通过以类似的方式添加其他变量Zidx来实现。

<强>注意事项

当您转到矩阵的最右侧和底部时,这很有效 - 您将获得较小的列表(如您指定的那样)。但是,numpy索引(和Python),包装,因此-1的索引将为您提供最后一个元素。因此,要求0,0处的偏移量仍然可以通过环绕来给你八个条目。这里的其他答案显示了检查这一点的好方法。

如果你想在左侧边缘抓取一些东西(并且你真的不想使用if语句),你可以改变索引(确保删除如上所述的中心元素):

# Create the nearest neighbors (ON THE LEFT EDGE)
Xidx_left, Yidx_left = mgrid[0:k+1,-k:k+1]

答案 2 :(得分:0)

没有坐标的代码?你的意思是这样的:

XMAX = 800
YMAX = 570

NEIGHBOURS = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]

matrix = range(XMAX * YMAX)

def all_neighbours(m):
    for i in xrange(len(m)):
        ns = []
        y, x = divmod(i, XMAX)
        for u, v in NEIGHBOURS:
            ux = u + x
            vy = v + y
            if 0 <= ux < XMAX and 0 <= vy < YMAX:
                ns.append(ux + vy * YMAX)
        yield i, ns

if __name__ == '__main__':

    for field, neighbours in all_neighbours(matrix):
        print field, neighbours