高效的Python方式将值映射到网格上

2 投票
4 回答
2841 浏览
提问于 2025-04-17 08:06

我有一个一维的网格,这个网格是由一系列已经排好序的浮点数值组成的。虽然这些点之间的距离不一样,但可以保证没有两个点是重合的(也就是距离不会等于0)。

我需要找到一种最有效的方法,把任何给定的数值“吸附”到离它最近的网格点上。我想到的最聪明的方法是这样的(npnumpy,而 myGrid 是一个 numpy 的 array

absDiff = np.abs(myGrid - myValue)
ix = np.argmax(absDiff)
snappedValue = myGrid[ix]

问题是,这种方法太慢了,我需要一种更高效的解决方案。

4 个回答

0

在一般情况下,你的新点会落在网格中两个已有点之间。你需要用二分查找的方法来找到这两个点,然后选择离你新点最近的一个。就这么简单。

接下来要做的就是正确处理一些特殊情况:比如当新点在第一个点之前,或者在最后一个点之后,还有当新点正好落在已有点上时。

4

我写了一个处理numpy数组的函数:

def ndsnap(points, grid):
    """
    Snap an 2D-array of points to values along an 2D-array grid.
    Each point will be snapped to the grid value with the smallest
    city-block distance.

    Parameters
    ---------
    points: 2D-array. Must have same number of columns as grid
    grid: 2D-array. Must have same number of columns as points

    Returns
    -------
    A 2D-array with one row per row of points. Each i-th row will
    correspond to row of grid to which the i-th row of points is closest.
    In case of ties, it will be snapped to the row of grid with the
    smaller index.
    """
    grid_3d = np.transpose(grid[:,:,np.newaxis], [2,1,0])
    diffs = np.sum(np.abs(grid_3d - points[:,:,np.newaxis]), axis=1)
    best = np.argmin(diffs, axis=1)
    return grid[best,:]
2

这段代码的意思是……

首先,它会做一些检查,确保一切正常。接着,它会执行一些操作,比如计算、处理数据或者与其他程序进行交流。最后,它会返回一个结果,告诉你它做了什么。

如果你对代码的某个部分不太明白,可以想象成是一个机器在完成任务,每一步都是机器需要做的工作。希望这样能帮助你更好地理解这段代码!

import bisect
def snap(myGrid, myValue):
    ix = bisect.bisect_right(myGrid, myValue)
    if ix == 0:
        return myGrid[0]
    elif ix == len(myGrid):
        return myGrid[-1]
    else:
        return min(myGrid[ix - 1], myGrid[ix], key=lambda gridValue: abs(gridValue - myValue))

撰写回答