Python 在二维numpy栅格中查找相邻图元

Python 在二维numpy栅格中查找相邻图元,python,arrays,numpy,grid,boundary,Python,Arrays,Numpy,Grid,Boundary,我有一个2D Numpy数组,看起来像这样: [[1,1,1,2,2], [1,1,1,2,2], [1,2,2,2,2]] [[False, False, True, False], ...etc 其中,数组中的每个数字表示一个区域。我想生成一个布尔数组,在相邻元素不完全相等的位置上,即在区域边界上,显示True。所以结果应该是这样的: [[1,1,1,2,2], [1,1,1,2,2], [1,2,2,2,2]] [[False, False, True, False], ..

我有一个2D Numpy数组,看起来像这样:

[[1,1,1,2,2],
 [1,1,1,2,2],
 [1,2,2,2,2]]
[[False, False, True, False],
...etc
其中,数组中的每个数字表示一个区域。我想生成一个布尔数组,在相邻元素不完全相等的位置上,即在区域边界上,显示
True
。所以结果应该是这样的:

[[1,1,1,2,2],
 [1,1,1,2,2],
 [1,2,2,2,2]]
[[False, False, True, False],
...etc

我知道一个简单的双for循环可以做到这一点,但我需要更快的东西。

一般来说,你需要一个边缘检测过滤器

处理这个问题的方法不止一种,但基本思想是用数据卷积一个简单的过滤器,如
[-1,1]
[-1,0,1]
scipy.ndimage
和scikit image是这方面的良好起点。请记住,处理一般情况的方法不止一种

但是,如果希望得到最简单的情况,可以使用基本的numpy操作:

import numpy as np

x = np.array([[1,1,1,2,2],
              [1,1,1,2,2],
              [1,2,2,2,2]])

edges = np.abs(np.diff(x, axis=1)) > 0
这将产生:

array([[False, False,  True, False],
       [False, False,  True, False],
       [ True, False, False, False]], dtype=bool)

如果希望输出与输入具有相同的形状,可以使用几个不同的选项。您可以用左侧或右侧边缘值填充输入数组:

# Pad the right-hand side with the edge values
# Use [(0, 0), (1, 0)] to pad the left instead.
xpad = np.pad(x, [(0, 0), (0, 1)], mode='edge')

edges = np.abs(np.diff(xpad, axis=1)) > 0
这将产生:

array([[False, False,  True, False, False],
       [False, False,  True, False, False],
       [ True, False, False, False, False]], dtype=bool)
在这种特定情况下,可以使用
np.gradient
而不是填充数组<代码>渐变将在边缘使用不同的算法,以确保保持阵列大小:

dy, dx = np.gradient(x)
edges = np.abs(dx) > 0
这会产生稍厚的边框,因为它使用的算法与简单减去相邻元素的算法略有不同:

array([[False, False,  True,  True, False],
       [False, False,  True,  True, False],
       [ True,  True, False, False, False]], dtype=bool)
最后,根据您所说的“双边界”的含义,您可能会尝试使用比简单的单边差异更复杂的边缘过滤器。例如:

In [4]: import scipy.ndimage

In [5]: abs(scipy.ndimage.laplace(x)) > 0
Out[5]:
array([[False, False,  True,  True, False],
       [False,  True,  True,  True, False],
       [ True,  True,  True, False, False]], dtype=bool)

有没有办法使输出与输入的大小相同,从而获得某种“双边框”效果?@user3396592-有几种不同的方法。您可以填充输入(例如,
np.pad
),但在这种特定情况下,您可能会发现使用
np.gradient
而不是
np.diff
最简单。我将添加一个示例。