Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 性能问题:查找点所在的多边形_Python_Python 3.x_Performance_Dictionary_For Loop - Fatal编程技术网

Python 性能问题:查找点所在的多边形

Python 性能问题:查找点所在的多边形,python,python-3.x,performance,dictionary,for-loop,Python,Python 3.x,Performance,Dictionary,For Loop,我目前有一个工作脚本,但我遇到了性能问题 我想要的是:获得建筑物的高度 我拥有的:一个文件,上面有我感兴趣的建筑物的GPS坐标(数百万,可能有/某些重复),都位于荷兰 荷兰每栋建筑高度的档案。这是一个GML文件,但我无法使用networkx正确加载它,因此我使用xml.etree.ElementTree解决了这个问题,将其作为xml文件处理。如果你愿意,可以下载 方法:从GML文件中,我能够为每一个以多边形轮廓坐标为关键点、高度为值的建筑(大约300万)建立一个字典。 例如: dictHeigh

我目前有一个工作脚本,但我遇到了性能问题

我想要的是:获得建筑物的高度

我拥有的:一个文件,上面有我感兴趣的建筑物的GPS坐标(数百万,可能有/某些重复),都位于荷兰 荷兰每栋建筑高度的档案。这是一个GML文件,但我无法使用networkx正确加载它,因此我使用xml.etree.ElementTree解决了这个问题,将其作为xml文件处理。如果你愿意,可以下载

方法:从GML文件中,我能够为每一个以多边形轮廓坐标为关键点、高度为值的建筑(大约300万)建立一个字典。 例如:

dictHeights = {((157838.00015090595, 461662.000273708), (157838.00015090595, 461662.000273708), (157781.32815085226, 461515.93227361), (157781.32815085226, 461515.93227361), (157781.32815085226, 461515.93227361)): 9.41, ...}
我能够使用以下两个自制函数循环遍历所有关键点并找到高度,这很好,但是,由于我处理数百万个点(地址)和多边形(建筑物),我遇到了严重的性能问题。只需要几分钟就可以达到5个高度。。。一种解决方案可能是使用树结构,但我看不出这将如何充分减少运行时间,因为我要么需要构建一个耗时的巨树,要么树很小,然后所有步骤都很耗时。基本上,如果可能的话,我想去掉大for循环

import numpy as np
import matplotlib.path as mpltPath
这个功能是瓶颈 我不太确定如何创建虚拟数据来复制我的数据。我的主要来源是。问题是如何正确地创建dict

# random points set of points to test 
N = 1000 #this should be about 4 million
points = zip(np.random.random(N),np.random.random(N))

#this creates a an array of polygons,but they overlap, and don't in my data.
lenpoly = 100 
M = 100 # this should be about 3 million

polygons = tuple([tuple((np.sin(x)+0.5,np.cos(x)+0.5) for x in np.linspace(np.pi,lenpoly)[:-1]) for m in np.random.random(M)])

#create array of virtual heights
heights = 100*np.random.random_sample(M)
下面这行是一个只有1个条目的dict,我已经尝试了大约1000种方法以我想要的方式构建dict(所有多边形都作为关键点,高度作为值),但我无法做到。。。要么是
polygons
是一个生成器,要么是M个生成器,要么是它应该是的(就像现在),但是字典不能正常工作

dictHeights = dict((polygon, height) for polygon, height in zip(polygons, heights))

result = getMedianHeight(dictHeights, points)
为了制作MWE,我将提供一小部分真实数据:

dictHeights = {((151922.594999999, 601062.109999999), (151915.193, 601067.614999998), (151919.848000001, 601073.874000002), (151927.25, 601068.368999999), (151922.594999999, 601062.109999999)): 9.16, ((151229.125999998, 601124.223999999), (151231.934, 601113.313000001), (151225.774, 601111.728), (151222.965999998, 601122.638999999), (151229.125999998, 601124.223999999)): 7.695}
points = [(157838.00015090595, 461662.000273708), (157838.00015090595, 461662.000273708), (157781.32815085226, 461515.93227361), (157781.32815085226, 461515.93227361), (157781.32815085226, 461515.93227361)]
result = getMedianHeight(dictHeights, points)

注意:由于dict中的多边形不是正确的建筑物,因此此MWE的结果对于所有点都是-999,但您应该得到点:-)

为什么不在加载时将数据拆分为纬度/经度的粗略度(或分)树?然后,您可以仅选择搜索点的相交子集(最多2x2,除非有跨越超过1度/分钟的建筑),并仅在该子集中与建筑进行碰撞测试,而不是检查整个数据集中的每个建筑。这是你能做的最粗糙的优化,但它应该会极大地提高你的性能,尽管在乌得勒支/阿姆斯特丹搜索一个点时,它会比在弗里斯兰搜索一个点慢。我已经考虑过这个问题(但我还不知道如何构建子集/树结构)但我认为这并不能解决问题:要么你有很多小的分支/子集,要么你最终只有很少的大分支/子集。拥有更多子集会导致找到正确子集的时间更长,但在子集内搜索速度更快。这当然是一种折衷,但如果存在快速解决方案,找到最佳平衡将是一项非常耗时的任务。。。那么,对于如何实施你的想法,你有什么指导吗?你有没有试过分块实施?我认为如果你写代码,你会看到它会快得多
dictHeights = {((151922.594999999, 601062.109999999), (151915.193, 601067.614999998), (151919.848000001, 601073.874000002), (151927.25, 601068.368999999), (151922.594999999, 601062.109999999)): 9.16, ((151229.125999998, 601124.223999999), (151231.934, 601113.313000001), (151225.774, 601111.728), (151222.965999998, 601122.638999999), (151229.125999998, 601124.223999999)): 7.695}
points = [(157838.00015090595, 461662.000273708), (157838.00015090595, 461662.000273708), (157781.32815085226, 461515.93227361), (157781.32815085226, 461515.93227361), (157781.32815085226, 461515.93227361)]
result = getMedianHeight(dictHeights, points)