基于NumPy优化点云转体素网格的最大采样方法
用NumPy矢量化实现点云最大采样
当然可以用NumPy的矢量化操作替代慢得离谱的Python for循环,核心是用np.maximum.at方法——它专门用来对数组指定索引位置的元素,原地执行取最大值的更新操作,完美匹配你的需求。
方法一:按通道分别处理(简洁高效)
这种方式只需要对3个通道做一次轻量循环(Python层仅循环3次,远低于百万级的逐点循环),其余运算都是NumPy内部的C级矢量化操作:
import numpy as np N = 1000000 coords = np.random.randint(0, 256, size=(N, 3)) vals = np.random.rand(N, 3) grid = np.zeros((3, 256, 256, 256), dtype=np.float16) # 替代原for循环的矢量化实现 for c in range(3): # 对第c个通道,在coords对应的(x,y,z)位置取最大值 np.maximum.at(grid[c], tuple(coords.T), vals[:, c])
方法二:单步跨通道处理(无Python循环)
如果想彻底去掉Python层循环,可以构造跨通道的索引数组,一次性完成所有更新:
import numpy as np N = 1000000 coords = np.random.randint(0, 256, size=(N, 3)) vals = np.random.rand(N, 3) grid = np.zeros((3, 256, 256, 256), dtype=np.float16) # 构造跨通道的索引数组 channels = np.tile(np.arange(3), N) # 每个点对应3个通道,shape (3*N,) x = np.repeat(coords[:, 0], 3) y = np.repeat(coords[:, 1], 3) z = np.repeat(coords[:, 2], 3) vals_flat = vals.flatten() # 把数值展平为一维,对应每个索引位置 # 一次性完成所有位置的最大值更新 np.maximum.at(grid, (channels, x, y, z), vals_flat)
为什么这两种方式更快?
原代码的for循环是Python层面逐点遍历,每一次循环都要做Python级别的变量解析、索引计算;而np.maximum.at是NumPy底层实现的矢量化操作,所有运算都在C级别完成,能充分利用CPU的并行优化,处理百万级数据的速度会提升几十甚至上百倍。
内容的提问来源于stack exchange,提问作者Layman
相关产品推荐
相关产品推荐

