列出相邻单元格

3 投票
3 回答
2764 浏览
提问于 2025-04-17 12:52

我有一个570行800列的矩阵,里面存的是一些ID值。我想做的是找到每个项目的相邻邻居。每个项目最多可以有8个邻居,除非这个项目在边界上,那样的话最多只有3个邻居。我想把这些邻居添加到一个列表里。我看到过一个帖子,讲的是如何根据每个单元格的x和y坐标来找到邻居,这个帖子对我很有帮助,但我不知道该如何修改代码,因为我没有坐标。我的ID是以字符串的形式出现的,这没问题,因为我会把它当作字典中的一个键。任何帮助都非常感谢。

3 个回答

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 的值,你可以轻松获取下一个最近的邻居,甚至是下下个邻居等等。此外,通过添加一个额外的变量 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]
5

假设你想在一个矩阵上构建一个八连通的网格,也就是说,每个位置都有上下左右以及对角线的连接。矩阵中的每个物品的位置可以用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
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

撰写回答