python - 性能问题:查找点位于哪个多边形中
问题描述
我目前有一个工作脚本,但我遇到了性能问题。
我想要的是:获得建筑物的高度。
我所拥有的:一个包含我感兴趣的建筑物的 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
这个功能是瓶颈
def getMedianHeight(dictHeights, points):
heights = []
for point in points:
found = False
for key, value in dictHeights.items():
path = mpltPath.Path(key)
if path.contains_point(point):
heights.append(value)
found = True
break
if not found:
heights.append(-999)
return heights
我不太确定如何创建虚拟数据来复制我的数据。我的主要来源是这里。问题是以正确的方式创建字典。
# 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)
注意:这个 MWE 的结果对于所有点都是 -999,因为 dict 中的多边形不是正确的建筑物,但你应该明白这一点:-)
解决方案
推荐阅读
- javascript - Framer API 滚动组件水平滚动 - React
- python - 来自 Codewars 的超市队列编程问题
- java - ScrollView 中的 Android Studio ScrollView
- ruby - 如何使用 ruby 和 ARGV 在目录中创建目录
- python - Python:在 numpy 数组中查找最大值和不连续点
- javascript - 如何安排图像相关元素的响应式但绝对定位?
- laravel - 如何从 laravel 控制器中的 3 个(多个)表中搜索数据?
- angular - Ionic Angular ion-reorder-group inside ion-reorder-group
- javascript - 在 .net 核心中发布到控制器时,无法让 .ajax 给出值
- asp.net-mvc - 是否可以使用相同的应用程序为不同的用户提供不同的数据库?