【问题标题】:Euclidean distance of Delaney triangulation - ScipyDelaney三角剖分的欧几里得距离 - Scipy
【发布时间】:2021-02-08 07:23:39
【问题描述】:

Scipy导入的spatial包可以测量指定点之间的欧几里得距离。是否可以使用Delaunay 包返回相同的测量值?使用下面的df,测量所有点之间的平均距离,并按Time 分组。但是,我希望使用 Delaunay 三角测量来测量平均距离。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial import Delaunay

df = pd.DataFrame({
    'Time' : [1,1,1,1,2,2,2,2],                  
    'A_X' : [5, 5, 6, 6, 4, 3, 3, 4], 
    'A_Y' : [5, 6, 6, 5, 5, 6, 5, 6],                         
        })

def make_points(x):
    return np.array(list(zip(x['A_X'], x['A_Y'])))

points = df.groupby("Time").apply(make_points)

for p in points:
    tri = Delaunay(p)
    ax.triplot(*p.T, tri.simplices)

所有点之间的平均距离可以使用以下方法测量,但我希望将 Delaunay 纳入其中。

 avg_dist = (df.groupby(['Time'])
             .apply(lambda x: spatial.distance.pdist
             (np.array(list(zip(x['A_X'], x['A_Y']))))
             .mean() if len(x) > 1 else 0)
             .reset_index()
             )

预期输出:

   Time         0
0     1  1.082842
1     2  1.082842

【问题讨论】:

    标签: python pandas scipy delaunay


    【解决方案1】:

    可以尝试此功能

    from itertools import combinations
    import numpy as np
        
    def edges_with_no_replacement(points):
        
        # get the unique coordinates
        points = np.unique(points.loc[:,['A_X','A_Y']].values,return_index=False,axis=0)
        if len(points) <= 1: return 0
        # for two points, no triangle
        # I think return the distance between the two points make more sense? You can change the return value to zero.
        if len(points) == 2: return np.linalg.norm(points[0]-points[1])
        
        tri = Delaunay(points)
        triangles = tri.simplices
        # get all the unique edges 
        all_edges = set([tuple(sorted(edge)) for item in triangles for edge in combinations(item,2)])
        # compute the average dist 
        return np.mean([np.linalg.norm(points[edge[0]]-points[edge[1]]) for edge in all_edges])
    

    此功能将首先找到给定三角形的所有唯一边缘,然后返回三角形边缘的平均长度。应用此功能

    avg_dist = (df.groupby(['Time']).apply(edges_with_no_replacement).reset_index())
    

    输出是

        Time    0
    0   1   1.082843
    1   2   1.082843
    

    请注意,edges_with_no_replacement将抛出QhullError如果点位于同一行,例如

    Delaunay(np.array([[1,2],[1,3],[1,4]]))
    

    所以,你必须确保点不在同一条线上。

    【讨论】:

    • 抱歉,只是一个快速的。我会修改这个问题,但如果我没有足够的点来计算,我希望返回一个0.但是我收到错误:QhullError: QH6214 qhull input error: not enough points(2) to construct initial simplex (need 4) While executing: | qhull d Qc Q12 Qz Qbb Qt Options selected for Qhull 2019.1.r 2019/06/21: run-id 974469614 delaunay Qcoplanar-keep Q12-allow-wide Qz-infinity-point Qbbound-last Qtriangulate _pre-merge _zero-centrum Qinterior-keep _maxoutside 0 span>
    • @ jonboy我已经更新了我的帖子,edges_with_no_replacement 现在可以在只有两个独特点时处理案例。但请注意,如果点在同一行上,该函数仍将抛出错误。 span>
    • 谢谢。因此,如果0-1点,则返回0。如果是 2 个点,则返回它们之间的距离。对不起,如果点在同一条线上是什么意思?
    • @jonboy 不客气,在我更新的帖子中,我提供了一个示例,如果点在同一条线上,Delaunay 找不到三角形(因为毕竟没有三角形)。如果您在数据集中有这样的点,您还将收到QhullError span>
    猜你喜欢
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 2014-02-04
    • 1970-01-01
    相关资源
    最近更新 更多