【问题标题】:Removing points from list if distance between 2 points is below a certain threshold如果 2 个点之间的距离低于某个阈值,则从列表中删除点
【发布时间】:2018-01-12 22:06:44
【问题描述】:

我有一个点列表,只有当它们之间的距离大于某个阈值时,我才想保留列表中的点。因此,从第一个点开始,如果第一个点和第二个点之间的距离小于阈值,那么我将删除第二个点,然后计算第一个点和第三个点之间的距离。如果此距离小于阈值,则比较第一个点和第四个点。否则移动到第三和第四之间的距离,依此类推。

例如,如果阈值为 2,而我有

list = [1, 2, 5, 6, 10]

那么我会期待

new_list = [1, 5, 10]

谢谢!

【问题讨论】:

    标签: python list distance points threshold


    【解决方案1】:

    不是一个花哨的单行,但如果当前值大于新列表中的最后一个值,您可以迭代列表中的值并将它们附加到某个新列表中,使用[-1]

    lst = range(10)
    diff = 3
    
    new = []
    for n in lst:
        if not new or abs(n - new[-1]) >= diff:
            new.append(n)
    

    之后,new[0, 3, 6, 9]


    关于您的评论“如果我有一个坐标列表(x,y)怎么办?”:在这种情况下,您会做完全相同的事情,只是您必须找到 @987654321 而不是仅比较数字@两点之间。所以,假设lst(x,y) 对的列表:

    if not new or ((n[0]-new[-1][0])**2 + (n[1]-new[-1][1])**2)**.5 >= diff:
    

    或者,您可以将 (x,y) 对转换为 complex 数字。对于这些,加法、减法、绝对值等基本运算已经定义好了,你可以再次使用上面的代码。

    lst = [complex(x,y) for x,y in lst]
    
    new = []
    for n in lst:
        if not new or abs(n - new[-1]) >= diff:  # same as in the first version
            new.append(n)
    print(new)
    

    现在,new 是表示点的复数列表:[0j, (3+3j), (6+6j), (9+9j)]

    【讨论】:

    • 谢谢,它有效。如果我有一个坐标列表(x,y)怎么办?我将如何更改代码?
    • 非常感谢,它很有帮助!
    【解决方案2】:

    虽然 tobias_k 的解决方案有效,但它并不是最有效的(在我看来,但我可能忽略了一些东西)。它基于列表顺序,不考虑在解决方案中最后排除与其他元素的最大数量接近(在阈值内)的元素。应首先考虑和检查具有最少数量的此类连接(或邻近)的元素。我建议的方法可能允许保留给定列表中其他元素超出指定阈值的最大点数。这对于向量列表以及 x,y 或 x,y,z 坐标非常有效。但是,如果您打算将此解决方案与标量列表一起使用,您可以简单地将这一行包含在代码 orig_list=np.array(orig_list)[:,np.newaxis].tolist()

    请看下面的解决方案:

    import numpy as np
    
    thresh = 2.0
    
    orig_list=[[1,2], [5,6], ...]
    
    nsamp = len(orig_list)
    arr_matrix = np.array(orig_list)
    distance_matrix = np.zeros([nsamp, nsamp], dtype=np.float)
    
    for ii in range(nsamp):
        distance_matrix[:, ii] = np.apply_along_axis(lambda x: np.linalg.norm(np.array(x)-np.array(arr_matrix[ii, :])),
                                                                  1,
                                                                  arr_matrix)
    
    
    n_proxim = np.apply_along_axis(lambda x: np.count_nonzero(x < thresh),
                                   0,
                                   distance_matrix)
    
    idx = np.argsort(n_proxim).tolist()
    idx_out = list()
    
    for ii in idx:
        for jj in range(ii+1):
            if ii not in idx_out:
                if self.distance_matrix[ii, jj] < thresh:
                    if ii != jj:
                        idx_out.append(jj)
    
    pop_idx = sorted(np.unique(idx_out).tolist(),
                     reverse=True)
    
    for pop_id in pop_idx:
        orig_list.pop(pop_id)
    
    nsamp = len(orig_list)
    

    【讨论】:

      猜你喜欢
      • 2023-03-30
      • 2016-08-09
      • 2018-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      • 2015-09-03
      相关资源
      最近更新 更多