高效的Python方式将值映射到网格上
我有一个一维的网格,这个网格是由一系列已经排好序的浮点数值组成的。虽然这些点之间的距离不一样,但可以保证没有两个点是重合的(也就是距离不会等于0)。
我需要找到一种最有效的方法,把任何给定的数值“吸附”到离它最近的网格点上。我想到的最聪明的方法是这样的(np
是 numpy
,而 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))