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

寻找支持2D三角分箱的Python工具及高效点归属判断方案

2D三角分箱的Python工具与高效实现方案

现成工具替代方案

目前没有直接对标scipy.stats.binned_statistic_dd的三角分箱专用包,但可以组合现有工具实现类似功能:

  • 用matplotlib.tri.Triangulation生成三角网格,结合numpy向量化操作或scipy.spatial的空间索引,自行实现分箱统计逻辑,满足三角分箱的统计需求。
  • 若只需可视化+基础统计,可基于matplotlib.tri的三角网格,手动统计每个三角内的点数、均值等指标。

自行实现的高效点-in-三角判断(10万级数据)

针对大规模数据集,核心是避免Python循环,通过向量化运算+空间索引优化性能:

1. 向量化重心坐标判断

利用numpy广播机制,一次性完成所有点与所有三角的归属判断,核心原理是通过重心坐标参数判断点是否在三角内部:

import numpy as np

def point_in_triangles(points, triangles):
    # points: 形状为(N, 2)的点数组
    # triangles: 形状为(M, 3, 2)的三角顶点数组,每个三角存储三个(x,y)坐标
    A = triangles[:, 0, :]
    B = triangles[:, 1, :]
    C = triangles[:, 2, :]

    # 计算向量与点积
    v0 = C - A
    v1 = B - A
    v2 = points[:, np.newaxis, :] - A

    dot00 = (v0 * v0).sum(axis=2)
    dot01 = (v0 * v1).sum(axis=2)
    dot02 = (v0 * v2).sum(axis=2)
    dot11 = (v1 * v1).sum(axis=2)
    dot12 = (v1 * v2).sum(axis=2)

    # 计算重心坐标的u、v参数
    inv_denom = 1 / (dot00 * dot11 - dot01 * dot01)
    u = (dot11 * dot02 - dot01 * dot12) * inv_denom
    v = (dot00 * dot12 - dot01 * dot02) * inv_denom

    # 判断点是否在三角内(含边界)
    return (u >= 0) & (v >= 0) & (u + v <= 1)

调用后会得到(N, M)的布尔数组,其中result[i,j]表示第i个点是否属于第j个三角。后续可通过numpy.argmax或掩码操作提取每个点对应的三角索引(需处理点不在任何三角的异常情况)。

2. 空间索引缩小候选范围

直接对所有三角做向量化判断仍可能存在性能瓶颈,可先通过空间索引筛选候选三角:

  • 用scipy.spatial.cKDTree为三角的包围盒中心构建索引,查询每个点附近的K个三角,只对这些候选三角做精确判断,大幅减少计算量。
  • 或者预先将平面划分为粗粒度矩形网格,把三角分配到对应的网格单元,点先定位到网格单元,再仅在单元内的三角中判断归属。

3. 结合分箱统计

拿到每个点的三角索引后,即可用numpy.bincount或scipy.stats.binned_statistic完成均值、求和等统计操作,实现类似binned_statistic_dd的功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 02:09:21