Подробнее о ответе Нолана Конавея:
Поскольку метрика Манхэттена используется в любом случае для полных прямоугольных сеток, следующее будет быстрее, если сетка станет достаточно большой:
def ndsnap_regular(points, *grid_axes):
snapped = []
for i, ax in enumerate(grid_axes):
diff = ax[:, np.newaxis] - points[:, i]
best = np.argmin(np.abs(diff), axis=0)
snapped.append(ax[best])
return np.array(snapped).T
Здесь grid_axes
просто содержит кортеж координат оси, который будет использоваться такими функциями, как numpy.meshgrid
для создания сетки из.
например. для привязки 100 трехмерных точек к сетке 50x50x50:
>>> n_points = 100
>>> points = np.random.random((n_points, 3))
>>> grid = (np.linspace(0, 1), np.linspace(0, 1), np.linspace(0, 1))
>>> grid_expanded = cartesian_product(*grid)
>>> len(grid_expanded)
125000
>>> %timeit ndsnap(points, grid_expanded)
418 ms ± 3.52 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
>>> %timeit ndsnap_regular(points, *grid)
86.5 µs ± 922 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> (ndsnap(points, grid_expanded) == ndsnap_regular(points, *grid)).all()
True