使用 Numpy 在坐标网格中排列和子采样 3D 点



我有一个 3d 点的列表,例如

np.array([
    [220, 114, 2000],
    [125.24, 214, 2519],
    ...
    [54.1, 254, 1249]
])

这些点没有有意义的顺序。我想以更好地表示坐标网格的方式对数组进行排序和重塑(这样我就有已知的宽度和高度,并且可以按索引检索 Z 值(。我还想将这些点向下采样为整数以处理碰撞。在下采样期间应用最小值、最大值或平均值。

我知道我可以使用 np.meannp.shape 对 1d 数组进行下采样

我目前使用的方法在 X,Y 中查找最小值和最大值,然后将 Z 值放入 2d 数组中,同时手动进行向下采样。

这会多次迭代巨型数组,我想知道是否有办法使用 np.meshgrid 或我忽略的其他一些 numpy 功能来做到这一点。

谢谢

您可以使用最有效的方法将数组排序到索引数组指定的箱中?要从y,x坐标获取索引数组,您可以使用np.searchsortednp.ravel_multi_index

这是一个示例实现,stb 模块是来自链接帖子的代码。

import numpy as np
from stb import sort_to_bins_sparse as sort_to_bins
def grid1D(u, N):
    mn, mx = u.min(), u.max()
    return np.linspace(mn, mx, N, endpoint=False)
def gridify(yxz, N):
    try:
        Ny, Nx = N
    except TypeError:
        Ny = Nx = N
    y, x, z = yxz.T
    yg, xg = grid1D(y, Ny), grid1D(x, Nx)
    yidx, xidx = yg.searchsorted(y, 'right')-1, xg.searchsorted(x, 'right')-1
    yx = np.ravel_multi_index((yidx, xidx), (Ny, Nx))
    zs = sort_to_bins(yx, z)
    return np.concatenate([[0], np.bincount(yx).cumsum()]), zs, yg, xg
def bin(yxz, N, binning_method='min'):
    boundaries, binned, yg, xg = gridify(yxz, N)
    result = np.full((yg.size, xg.size), np.nan)
    if binning_method == 'min':
        result.reshape(-1)[:len(boundaries)-1] = np.minimum.reduceat(binned, boundaries[:-1])
    elif binning_method == 'max':
        result.reshape(-1)[:len(boundaries)-1] = np.maximum.reduceat(binned, boundaries[:-1])
    elif binning_method == 'mean':
        result.reshape(-1)[:len(boundaries)-1] = np.add.reduceat(binned, boundaries[:-1]) / np.diff(boundaries)
    else:
        raise ValueError
    result.reshape(-1)[np.where(boundaries[1:] == boundaries[:-1])] = np.nan
    return result
def test():
    yxz = np.random.uniform(0, 100, (100000, 3))
    N = 20
    boundaries, binned, yg, xg = gridify(yxz, N)
    binmin = bin(yxz, N)
    binmean = bin(yxz, N, 'mean')
    y, x, z = yxz.T
    for i in range(N-1):
        for j in range(N-1):
            msk = (y>=yg[i]) & (y<yg[i+1]) & (x>=xg[j]) & (x<xg[j+1])
            assert (z[msk].min() == binmin[i, j]) if msk.any() else np.isnan(binmin[i, j])
            assert np.isclose(z[msk].mean(), binmean[i, j]) if msk.any() else np.isnan(binmean[i, j])

相关内容

  • 没有找到相关文章

最新更新