【问题标题】:How can I remove points from a list which are close to points in another list by some distance如何从列表中删除与另一个列表中的点相距一定距离的点
【发布时间】:2019-12-18 20:12:26
【问题描述】:

我有 2 个图像中点的坐标列表。

说,

List1 = [[2,3],[4,5],[10,20],[45,60]]
List2 = [[100,50],[65,48],[58,32],[98,45]...............[655,254],[232,545]]

dist = 20

List1 将有 5 或 6 个元素。 List2 可以有超过 1000 个元素。

我想生成一个list3,其中我只有来自List2 的坐标,其与List1 中所有点的欧几里得距离大于dist=20

基本上,我的目标是从List2 中删除与List1 中的点相距一定距离的所有点。

目前,我正在做这样的事情

from scipy.spatial.distance import cdist

def newlist(list1, list2, dist):
    edist = cdist(list2, list1)
    highvalues = edist > dist
    edist[highvalues] = 0
    edist[~highvalues] = 1
    indx = edist.sum(axis=1)
    list3 = [list2[i] for i, e in enumerate(indx) if e == 0]

    return list3

运行时间:52us

【问题讨论】:

  • 1.遍历列表 2 的项目 | 2. 在第一个循环中,遍历列表 1 的项目并使用 numpy.linalg.norm() 计算距离 | 3. 如果全部匹配,则将列表 1 的项追加到三个

标签: python list filtering coordinates euclidean-distance


【解决方案1】:
List3= [p for p in List2 if all(cdist(i,p)>20 for i in List1)]

【讨论】:

    【解决方案2】:

    对于 cal 欧几里得距离,您必须从 scipy.spatial.distance 导入 euclidean

    from scipy.spatial.distance import euclidean
    new_list=[]
    for i in List2:
        for j in List1:
            if euclidean(i,j)>20:
                continue        
        new_list.append(i)
    

    【讨论】:

    • 我会使用元组(对于大型列表应该更节省内存,您可以很容易地对其应用 set() 操作:new_list=[tuple(i) for i in List2 for j in List1 if euclidean(i,j)>20 ]
    • 你是对的,但也许用户需要一个坐标列表?并且需要在其他地方使用它们!
    • @Kasra 我相信这比我的解决方案需要更多时间。我将在 1000 个列表上运行。无论如何我们可以避免循环?
    • 要查找拖车代码的时间,请在终端尝试time python file_name.py 并查看两者的时间并给我结果!谢谢
    • 我在 ipython 中使用了 %timeit 对于我的方法:52 us 对于这个方法:400us
    【解决方案3】:

    可以在 NumPy 中使用 boolean array indexingnp.all,而不是使用低效的 for 循环:

    import numpy as np
    from scipy.spatial.distance import cdist
    
    points = np.array([[0,1], [2,0], [4,5], [6,7], [9,9], [8,10]])
    reference = np.array([[0,0], [10,10]])
    distance = 3
    
    filtered_points = points[np.all(cdist(points, reference) >= distance, axis=1)]
    print(filtered_points)
    # array([[4, 5],
    #        [6, 7]])
    

    请注意,您还可以将欧几里得度量更改为任何其他度量。有关详细信息,请参阅docs on scipy.spatial.distance.cdist。例如,对于曼哈顿距离,人们会改为写cdist(points, reference, metric='cityblock')

    【讨论】:

      猜你喜欢
      • 2011-02-07
      • 2023-04-03
      • 1970-01-01
      • 2019-03-31
      • 2018-01-12
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 2019-08-04
      相关资源
      最近更新 更多