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

如何保存支持增量添加点的预计算Voronoi图至文件?

解决Scipy增量Voronoi图无法序列化的问题

Scipy的Voronoi对象无法通过pickle/dill序列化,核心原因是其底层依赖的_qh是Qhull的C语言结构,无法被转换为可序列化的Python对象。以下是几种可行的解决方案:

方案1:保存原始点集,重新构建增量Voronoi

这是最直接的方案,虽然会有重建开销,但1e6个二维点的Voronoi构建时间在多数硬件上处于可接受范围(几秒到十几秒):

  • 保存原始点集:
import numpy as np
np.save("voronoi_points.npy", points)
  • 后续加载并重建:
import numpy as np
from scipy.spatial import Voronoi

points = np.load("voronoi_points.npy")
vor = Voronoi(points, incremental=True)

方案2:手动序列化Voronoi核心状态(进阶)

手动保存增量Voronoi的关键属性,后续通过初始化空对象并恢复状态来实现复用:

  1. 保存核心数据:
import numpy as np

save_data = {
    "points": vor.points,
    "vertices": vor.vertices,
    "regions": np.array(vor.regions, dtype=object),
    "ridge_points": vor.ridge_points,
    "ridge_vertices": vor.ridge_vertices,
    "npoints": np.array(vor.npoints),
    "incremental": np.array(vor.incremental)
}

np.savez("voronoi_state.npz", **save_data)
  1. 加载并恢复状态:
import numpy as np
from scipy.spatial import Voronoi

loaded_data = np.load("voronoi_state.npz", allow_pickle=True)

# 初始化空的增量Voronoi对象
vor = Voronoi([[0,0]], incremental=True)
# 覆盖初始状态
vor.points = loaded_data["points"]
vor.vertices = loaded_data["vertices"]
vor.regions = loaded_data["regions"].tolist()
vor.ridge_points = loaded_data["ridge_points"]
vor.ridge_vertices = loaded_data["ridge_vertices"]
vor.npoints = loaded_data["npoints"].item()
vor.incremental = loaded_data["incremental"].item()

# 继续添加新点
new_point = np.array([[10.0, 10.0]])
vor.add_points(new_point)

注意:该方案依赖Scipy Voronoi的内部属性结构,不同版本可能存在兼容性问题,使用前需测试。

方案3:换用支持序列化的Voronoi实现

如果对重建开销敏感,可以考虑:

  • 使用pyhull等Qhull原生绑定库,直接操作并保存Qhull的内部状态
  • 手动实现增量Voronoi算法,完全控制数据结构以支持自由序列化

内容的提问来源于stack exchange,提问作者yik_him

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 12:53:17