如何在ndarray中查找单元的邻居?

hkk*_*hkk 1 python arrays numpy scipy multidimensional-array

我正在使用Python中的n维数组,并且我想根据其坐标查找给定单元的“邻居”(相邻单元)。问题是我事先不知道尺寸数。

我试图numpy.roll按照此答案的建议使用,但似乎不清楚如何将此方法应用于多个维度。

请指出正确的方向。

ali*_*i_m 5

我将假设您有一个(ndims,)索引向量指定一个点p,并且您想要一个(m, ndims)索引数组,该索引数组对应于数组中每个相邻元素(包括对角相邻的元素)的位置。

从索引向量开始p,您希望通过-1、0和+1的每种可能组合来偏移每个元素。可以使用np.indices生成(m, ndims)偏移量数组,然后将这些偏移量添加到中来完成此操作p

您可能要排除点p本身(即where offset == np.array([0, 0, ..., 0]),并且可能还需要排除越界索引)。

import numpy as np

def get_neighbours(p, exclude_p=True, shape=None):

    ndim = len(p)

    # generate an (m, ndims) array containing all strings over the alphabet {0, 1, 2}:
    offset_idx = np.indices((3,) * ndim).reshape(ndim, -1).T

    # use these to index into np.array([-1, 0, 1]) to get offsets
    offsets = np.r_[-1, 0, 1].take(offset_idx)

    # optional: exclude offsets of 0, 0, ..., 0 (i.e. p itself)
    if exclude_p:
        offsets = offsets[np.any(offsets, 1)]

    neighbours = p + offsets    # apply offsets to p

    # optional: exclude out-of-bounds indices
    if shape is not None:
        valid = np.all((neighbours < np.array(shape)) & (neighbours >= 0), axis=1)
        neighbours = neighbours[valid]

    return neighbours
Run Code Online (Sandbox Code Playgroud)

这是一个易于可视化的2D示例:

p = np.r_[4, 5]
shape = (6, 6)

neighbours = get_neighbours(p, shape=shape)

x = np.zeros(shape, int)
x[tuple(neighbours.T)] = 1
x[tuple(p)] = 2

print(x)
# [[0 0 0 0 0 0]
#  [0 0 0 0 0 0]
#  [0 0 0 0 0 0]
#  [0 0 0 0 1 1]
#  [0 0 0 0 1 2]
#  [0 0 0 0 1 1]]
Run Code Online (Sandbox Code Playgroud)

这将推广到任何维度。


如果您只想为的“邻居”建立索引,p而又不在乎排除p自身,那么一个更简单,更快捷的选择是使用slice对象元组:

idx = tuple(slice(pp - 1, pp + 2) for pp in p)
print(x[idx])
# [[1 1]
#  [1 2]
#  [1 1]]
Run Code Online (Sandbox Code Playgroud)