微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

去除彼此靠近的二维点

如何解决去除彼此靠近的二维点

我想删除彼此靠近或重复的坐标。

例如

x = [[9,169],[5,164],[340,210],[1020,102],[210,312],[12,150]]

在上面的列表中,第一个和第二个元素彼此靠近。如何在保留第一个元素的同时删除第二个元素?

以下是我尝试过的,

def process(input_list,thresh=(10,10)):
    buffer = input_list.copy()
    n = 0
    prev_cx,prev_cy = 0,0
    for i in range(len(input_list)):
        elem = input_list[i]
        cx,cy = elem
        if n == 0:
            prev_cx,prev_cy = cx,cy
        else:
            ab_cx,ab_cy = abs(prev_cx - cx),abs(prev_cy - cy)
            if ab_cx <= thresh[0] and ab_cy <= thresh[1]:
                del buffer[i]
        n += 1
    return buffer


x = [[9,150]]
processed = process(x)
print(processed)

问题在于它不会递归检查是否有任何其他重复项,因为它只检查相邻坐标。什么是过滤坐标的有效方法

阈值 = (10,10) 的样本输入:

x = [[12,24],12],[100,1020],[20,30],[121,214],[15,12]]

示例输出

x = [[12,214]]

解决方法

你的问题有点含糊,但我的意思是:

  1. 您想比较点的所有组合
  2. 如果组合包含比阈值更近的点
  3. 然后从输入列表的开头进一步删除点

试试这个:

import itertools

def process(input_list,threshold=(10,10)):
    combos = itertools.combinations(input_list,2)
    points_to_remove = [point2
                        for point1,point2 in combos
                        if abs(point1[0]-point2[0])<=threshold[0] and abs(point1[1]-point2[1])<=threshold[1]]
    points_to_keep = [point for point in input_list if point not in points_to_remove]
    return points_to_keep

coords = [[12,24],[5,12],[100,1020],[20,30],[121,214],[15,12]]
print(process(coords))
    
>>> [[12,214]]

这种工作方式是使用 itertools 生成点的所有组合(将点保留在原始顺序中),然后使用阈值创建要删除的点列表。然后它返回不在要删除的点列表中的点列表。

你会注意到我比你多一点。我只是简单地复制了您想要的功能(即 dy 和 dx 但是,如果我使用 AND 语句更改行以删除点 if dy OR dx

所以我要请您重新检查您的示例输出。

顺便说一句,确认分别检查 x 和 y 接近度是否是您真正想要的可能对您有用。所以作为奖励,我还包含了一个使用欧几里得距离的版本:

import itertools
import math

def process(input_list,threshold=100):
    combos = itertools.combinations(input_list,2)
    points_to_remove = [point2 for point1,point2 in combos if math.dist(point1,point2)<=threshold]
    points_to_keep = [point for point in input_list if point not in points_to_remove]
    return points_to_keep

coords = [[12,12]]
print(process(coords))

>>> [[12,214]]

当我使用阈值半径 100 时,此版本适合您的原始样本。

,

我想把它分开一点。当然,这也很棘手,因为您必须修改列表。

def remove_close_neighbors(input_list,thresh,position):
  target_item = input_list[position]
  return [item for i,item in enumerate(input_list) if i == position or not is_close(target_item,item,thresh)]

这将删除所有“重复”(或关闭)点,除了正在考虑的项目。

(然后定义is_close来检查阈值条件)

然后我们可以检查我们的项目:

def process(input_list,thresh):
  pos = 0
  while pos < len(input_list):
    input_list = remove_close_neighbors(input_list,pos)
    pos += 1

这绝不是实现这一目标的最有效方式。这取决于您需要的可扩展性。如果我们在谈论“一亿分”,您将需要研究巧妙的数据结构和算法。我认为 结构可能会很好,“按扇区”对点进行分组,因为这样您就不必一直将每个点与其他点进行比较。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?