Numpy - 跨多个坐标查找匹配项

Numpy - Finding matches across multiple co-ordinates

我正在使用 somoclu 生成一些数据的紧急自组织地图。获得 BMU(最佳匹配单元)后,我将对 BMU 的坐标执行 Delaunay 三角剖分,以便在 SOM 中找到每个 BMU 的邻居。

在下面的 Python 片段中,是否有更 Pythonic 版本的 a == c and b == d 条件句?换句话说,如何在不拆分单独坐标的情况下直接比较 bmupoint

points = np.unique(np.array(som.bmus), axis = 0)
for idx, bmu in enumerate(som.bmus):
    a, b = bmu
    for point_idx, point in enumerate(points):
        c, d = point
        if a == c and b == d: # More Pythonic version of this line?
            print (idx, point_idx)
            break

方法 #1

我们正在使用 NumPy 数组,因此我们可以利用 broadcasting 来实现矢量化解决方案 -

ar = np.array(som.bmus)
points = np.unique(ar, axis = 0)

mask = (ar[:,0,None]==points[:,0]) & (ar[:,1,None]==points[:,1])
indices = np.argwhere(mask)

接近 #1-G

获取 mask 的一种更紧凑的方法,它涵盖了通用编号。 ar 中的列数将为 -

mask = (ar[:,None] == points).all(axis=2)

方法 #2

通用编号的另一种memory-efficient方法。 cols 将与 viewsnp.searchsorted -

#  @Divakar
def view1D(a, b): # a, b are arrays
    a = np.ascontiguousarray(a)
    b = np.ascontiguousarray(b)
    void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
    return a.view(void_dt).ravel(),  b.view(void_dt).ravel()

n = len(ar)
indices = np.empty((n,2),dtype=int)
indices[:,0] = np.arange(n)
a,b = view1D(ar, points) # ar, points from app#1
indices[:,1] = np.searchsorted(b, a)

对于 numpy 个数组,您可以使用 np.array_equal。这测试相同的形状和相同的元素。

但如果您的逻辑与您的代码一样简单,请使用

points = np.unique(np.array(som.bmus), axis = 0)

for idx, bmu in enumerate(som.bmus):
    for point_idx, point in enumerate(points):
        if np.array_equal(bmu, point):
            print(idx, point_idx)
            break