You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用NumPy从邻居列表生成相邻三角形数组的技术问询

使用NumPy从邻居列表生成相邻三角形数组的技术问询

解决方案思路

你的核心需求是为每个点生成由[当前点, 邻居i, 邻居i+1]组成的三角形,其中最后一个三角形的邻居i+1要循环回到第一个邻居。当前代码的问题在于没有处理循环闭合,也没有把当前点加入到每个三角形中,而且zip_longest引入了不必要的None值。

下面是几个高效的实现方案:


方案一:利用NumPy的拼接和滑动窗口(向量化解法)

这种方法避免了显式循环,适合处理大规模数据:

import numpy as np
from numpy.lib.stride_tricks import sliding_window_view

# 原始输入数据
point_ids = np.array([0, 1, 2])  # 对应的点ID
numnbrs = np.array([4,4,5])
nbrs = np.array([12,  2, 39, 40,  56,  2,  9, 10,  0,  1,  5, 21, 19])

# 1. 拆分邻居列表为每个点对应的邻居数组
split_indices = np.cumsum(numnbrs)[:-1]
nbrs_per_point = np.split(nbrs, split_indices)

# 2. 对每个点的邻居列表,拼接第一个邻居到末尾,实现循环闭合
closed_nbrs = [np.concatenate([nb, [nb[0]]]) for nb in nbrs_per_point]

# 3. 生成滑动窗口,得到每个相邻邻居对
neighbor_pairs = [sliding_window_view(nb, 2) for nb in closed_nbrs]

# 4. 为每个点重复自身ID,和邻居对组合成三角形
triangles = []
for pid, pairs in zip(point_ids, neighbor_pairs):
    # 生成重复当前点ID的数组,形状和pairs一致
    pid_col = np.full((len(pairs), 1), pid)
    # 拼接成三角形数组
    triangles.append(np.hstack([pid_col, pairs]))

# 5. 合并所有三角形为最终数组
final_triangles = np.vstack(triangles)

运行后得到的final_triangles就是你想要的结果:

array([[ 0, 12,  2],
       [ 0,  2, 39],
       [ 0, 39, 40],
       [ 0, 40, 12],
       [ 1, 56,  2],
       [ 1,  2,  9],
       [ 1,  9, 10],
       [ 1, 10, 56],
       [ 2,  0,  1],
       [ 2,  1,  5],
       [ 2,  5, 21],
       [ 2, 21, 19],
       [ 2, 19,  0]])

方案二:简洁的列表推导式(适合小数据量)

如果你的数据量不大,用列表推导式会更直观,容易调试:

import numpy as np

point_ids = [0, 1, 2]
numnbrs = [4,4,5]
nbrs = [12,  2, 39, 40,  56,  2,  9, 10,  0,  1,  5, 21, 19]

# 拆分邻居列表
split_idx = np.cumsum(numnbrs)[:-1]
nbrs_per_point = np.split(nbrs, split_idx)

# 生成所有三角形
triangles = []
for pid, neighbors in zip(point_ids, nbrs_per_point):
    # 遍历每个邻居,和下一个邻居组合(最后一个邻居和第一个组合)
    for i in range(len(neighbors)):
        next_neighbor = neighbors[(i+1) % len(neighbors)]
        triangles.append([pid, neighbors[i], next_neighbor])

final_triangles = np.array(triangles)

为什么你的原始代码没成功?

  1. itertools.zip_longest是为了对齐不同长度的数组,但这里我们不需要对齐,反而引入了None值;
  2. 没有处理循环闭合的情况,最后一个邻居对应该是[最后一个邻居, 第一个邻居];
  3. 没有把当前点的ID加入到每个三角形数组中,这是生成目标数组的关键部分。

备注:内容来源于stack exchange,提问作者ashwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 13:39:29