【发布时间】:2018-07-09 20:54:56
【问题描述】:
我有 1100 万个 GPS 坐标要分析,效率是我的主要问题。问题如下: 我想在它周围每 50 米半径只保留 1 个 GPS 坐标(称之为节点)。所以代码非常简单,我有一个集合 G,对于 G 中的每个节点,我检查我要添加的节点是否与其他节点太接近。如果太近(
问题是集合 G 增长得非常快,最后要检查是否要向集合中添加一个节点,我需要对数百万个元素运行 for 循环...
这是 Node 类的简化代码:
from geopy import distance
class Node: #a point on the map
def __init__(self, lat, long): #lat and long in degree
self.lat = lat
self.long = long
def distanceTo(self, otherNode):
return distance.distance((self.lat, self.long), (otherNode.lat, otherNode.long)).km
def equivalent(self, otherNode):
return self.distanceTo(otherNode) < 0.05 #50 meters away
这是“添加”过程:
currentNode = Node(lat, long)
alreadyIn = False
for n in graph:
if n.equivalent(currentNode):
alreadyIn = True
break
#set of Nodes
if alreadyIn == False:
G.add(currentNode)
这不是节点聚类的问题,因为我没有尝试检测数据集中的任何模式。我只是想将 50 米半径内的节点分组。
我认为最好的数据结构是给定坐标返回True 或False(如果集合中有类似的节点)。但是我不知道要使用哪一个,因为我没有将环境划分为正方形而是圆形。 (是的,节点 A 可以等价于 B 和 C,而 B 和 C 不等价,但我并不介意......)。
感谢您的帮助!
【问题讨论】:
-
一定要用Python吗?
-
如果您不需要精确的距离,那么您可以获取纬度和经度的差异,然后使用平方和作为度量标准
Δlatitude² + Δlongitude² < k(50m)²,k将米转换为度。为了更准确,您可以根据纬度对经度进行校正。 -
是的,我需要使用 python。问题不在于@YiminRong 的准确性,我认为我的指标很好。问题是效率。我需要更快地添加集合中的节点,而无需检查集合中已有的数百万个节点。
-
另外,如果输入区域相对较小,即可以近似为一个平面,您可以定义一个 5° ⨉ 5° 的区域划分为更小的区域,然后将您的位置分类为他们。那么你只需要考虑最近的 9 个邻居作为候选。猜猜如果您的输入区域很大,它甚至会起作用。基本上,您会将它们作为一阶近似值添加到近似位置。
-
听起来不错,但我不知道该区域的大小。假设它很小,我需要在读取新节点时缩放 bin 的数量。我会用字典试试。谢谢!