如果在 2D 中,p(x,y),我想要一个 3*3 的相邻矩阵:
(x-1,y-1), (x,y-1), (x+1,y-1),
...
(x-1,y+1), (x,y+1), (x+1,y+1),
如果在 3D(3*3*3)、4D(3*3*3*3)、...中怎么办?
有更好的功能吗?
您也可以使用itertools.product
,具体取决于您喜欢的输出格式。它会比一种numpy
方法慢,但我发现它更容易理解:
from itertools import product
def adjacent_grid(centre):
steps = product([-1, 0, 1], repeat=len(centre))
return (tuple(c+d for c,d in zip(centre, delta)) for delta in steps)
这使
>>> list(adjacent_grid((3,)))
[(2,), (3,), (4,)]
>>> list(adjacent_grid((3,3)))
[(2, 2), (2, 3), (2, 4), (3, 2), (3, 3), (3, 4), (4, 2), (4, 3), (4, 4)]
>>> list(adjacent_grid((3,3,3)))
[(2, 2, 2), (2, 2, 3), (2, 2, 4), (2, 3, 2), (2, 3, 3), (2, 3, 4), (2, 4, 2), (2, 4, 3), (2, 4, 4), (3, 2, 2), (3, 2, 3), (3, 2, 4), (3, 3, 2), (3, 3, 3), (3, 3, 4), (3, 4, 2), (3, 4, 3), (3, 4, 4), (4, 2, 2), (4, 2, 3), (4, 2, 4), (4, 3, 2), (4, 3, 3), (4, 3, 4), (4, 4, 2), (4, 4, 3), (4, 4, 4)]
您可以通过在 numpy 中使用广播来获得结果:
import numpy as np
def p(*args):
args = np.array(args)
idx = np.array([-1, 0, 1])
a = np.broadcast_arrays(*np.ix_(*(args[:,None] + idx)))
return np.concatenate([x[..., None] for x in a], axis=-1)
结果形状是 2D 中的 (3,3,2),3D 中的 (3,3,3,3),4D 中的 (3,3,3,3,4):
>>> p(3, 8)
array([[[2, 7],
[2, 8],
[2, 9]],
[[3, 7],
[3, 8],
[3, 9]],
[[4, 7],
[4, 8],
[4, 9]]])