如何用Numpy高效构建网格点的有序序列索引数组?
高效生成网格面索引的Numpy实现方案
我们通过以下Numpy代码生成网格点(蓝色数字为位置索引):
# u、v参数分别定义x、y方向的网格点数量 u, v = (3, 3) x = np.linspace(0, 2, u) y = np.linspace(0, 1, v) # 用meshgrid生成网格坐标 xx, yy, zz = np.meshgrid(x, y, 0) # 重塑坐标数组形状 coords = np.dstack((xx, yy, zz)) coords = np.vstack(coords)
当u和v取任意大数值时,我们需要构建符合特定模式的索引数组,示例如下:
[[0 1 4 3] [1 2 5 4] [3 4 7 6] [4 5 8 7]]
目前已实现的方案为:
listing = np.array([((u)*j+i, (u)*j+i+1, (u)*j+i+u+1, (u)*j+i+u) for j in range(v-1) for i in range(u-1)])
更简洁高效的Numpy原生实现
我们可以利用Numpy的广播机制和数组切片操作,完全规避Python层面的循环,获得更优的性能与可读性:
# 生成按网格排列的基础索引矩阵 base_idx = np.arange(u * v).reshape(v, u) # 提取每个四边形面的四个顶点索引并组合 faces = np.stack([ base_idx[:-1, :-1].ravel(), # 左上顶点索引 base_idx[:-1, 1:].ravel(), # 右上顶点索引 base_idx[1:, 1:].ravel(), # 右下顶点索引 base_idx[1:, :-1].ravel() # 左下顶点索引 ], axis=1)
这个实现直接基于网格形态的索引矩阵进行切片,通过ravel()将二维切片展平为一维数组,再用stack按列组合成目标格式。相比列表推导,它充分利用了Numpy的底层C优化,在u、v数值较大时运行效率提升明显,代码逻辑也更直观易懂。
内容的提问来源于stack exchange,提问作者Certes
相关产品推荐
相关产品推荐

