【发布时间】:2016-10-27 09:32:17
【问题描述】:
我正在计算一个点和多个线段之间的测地线距离。每条线段都有一个唯一的标识号。我想从我的距离函数返回距离,以便它们本质上是联系在一起的。我还想保持功能,如对距离进行排序,并用标签或位置对它们进行索引,并取回距离数据和标签。类似于带有索引的 Pandas 系列,但我不能使用系列,因为数据返回到 Pandas DataFrame 中,然后扩展系列并弄得一团糟。这是一个例子:
In [1]: '''Note that all this happens inside an apply function of a Pandas Series'''
labels = [25622, 25621, 25620, 25619, 25618]
dist = vect_dist_funct(pt, labels) #vect_dist_funct does the computations, and returns distances in meters
dist
Out[1]: array([296780.2217658355, 296572.4476883276, 296364.21166884096,
296156.4366241771, 295948.6610171968], dtype=object)
然而,我想要的是这样的 dict,其中标签和距离本质上是相互关联的:
{25622 : 296780.2217658355,
25621 : 296572.4476883276,
25620 : 296364.21166884096,
25619 : 296156.4366241771,
25618 : 295948.6610171968}
但现在我失去了这些值的功能。我不能轻易地对它们进行排序,或者比较它们,或者任何东西。我查看了Numpy Structured Arrays,它们似乎可行,但如果我无法对距离进行排序并获得最近段的索引,那么它对我来说没有多大用处。还有其他我可以使用的数据类型吗?
长篇故事和背景
我正在尝试进行空间连接。通过在 RTree (example) 中搜索,我得到了一个点最有可能接近的段的索引。这些是标签中的索引。然后我查看线几何表以找到这些选定标签的线几何,并计算点到每个线段的距离。
接下来的步骤涉及检查空间连接的完整性。在某些情况下,最近不是最佳连接候选者,连接需要在其他参数上进行评估。因此,我的计划是从最近的部分向外工作。这将涉及对距离进行排序,并获取最近段的索引,然后使用该索引查看段表并提取线的其他属性以进行检查。如果可以确认匹配,则接受该段,否则,将其拒绝,并且算法将移动到下一个最近的段。
我正在寻找一种能够完成所有这些工作的数据类型,而不会破坏计算它的段的距离之间的联系。
使用 Pandas 的问题
这就是函数的实际调用方式:
joined = points['geometry'].apply(pointer, centroid=line['centroid'], tree_idx=tree_idx))
然后在pointer 内部,会发生这种情况:
def pointer(point, centroid, tree_idx):
intersect = list(tree_idx.intersection(point.bounds))
if len(intersect) > 0:
points = pd.Series([point.coords[0]]*len(intersect)).values
polygons = centroid.loc[intersect].values
dist = vect_dist_funct(points, polygons)
return pd.Series(dist, index=intercept, name='Dist').sort_values()
else:
return pd.Series(np.nan, index=[0], name='Dist')
然后,joined 看起来像这样:
这是因为未计算所有点(行是点)和所有线(列是线)之间的距离。这成本太高了(4M 点,每个状态 180k 行,整个数据集有 50 个状态)。此外,与我返回两个 Numpy 数组时相比,生成 joined 的这个 DataFrame 合并操作将运行时间增加了 7 倍。返回两个 Numpy 数组的问题在于,要始终保持距离和行 ID 对齐并不容易。
点、线、tree_idx 示例
请注意,这是在列和行中截断的数据集。我只包括相关列,而不包括其余数据:
点数:
geometry
id
88400001394219 0.00 POINT (-105.2363291 39.6988139)
0.25 POINT (-105.2372017334178 39.69899060448157)
0.50 POINT (-105.2380177896182 39.69933953105642)
0.75 POINT (-105.2387202141595 39.69988447162143)
1.00 POINT (-105.2393222 39.7005405)
88400002400701 0.00 POINT (-104.7102833 39.8318348)
0.25 POINT (-104.7102827 39.831966625)
0.50 POINT (-104.7102821 39.83209845)
0.75 POINT (-104.7102815 39.832230275)
1.00 POINT (-104.7102809 39.8323621)
所以这基本上是线上的插值点。 line id 是第一级索引,第二级是插值点的百分比。这形成了第一个数据集,我想将第二个数据集中的一些属性带到该数据集。
行:
geometry centroid
id
71345 POLYGON ((-103.2077992965318 40.58026765162965... (-103.20073265160862, 40.576450381964975)
71346 POLYGON ((-103.2069505830457 40.58155121711739... (-103.19987394433825, 40.57774903464972)
71347 POLYGON ((-103.2061017677045 40.58283487609803... (-103.19901204453959, 40.57905245493993)
71348 POLYGON ((-103.2052000154291 40.58419853220472... (-103.19815200508097, 40.58035300329024)
71349 POLYGON ((-103.2043512639656 40.58548197865339... (-103.19729445792181, 40.58164972491414)
71350 POLYGON ((-103.2035025651746 40.5867652936463,... (-103.1964362470977, 40.5829473948391)
71351 POLYGON ((-103.2026535431035 40.58804903349249... (-103.19557847342394, 40.58424434094705)
71352 POLYGON ((-103.201804801526 40.58933229190573,... (-103.19472966696722, 40.58552767098465)
71353 POLYGON ((-103.2009557884142 40.59061590473365... (-103.19388484652855, 40.58680427447224)
71354 POLYGON ((-103.2001001699726 40.59190793446012... (-103.19303392095904, 40.5880882237994)
这是第二个数据集的一部分(这个答案开头提到的标签是这个数据集的索引)。目标是以智能的方式将属性从该数据集传输到点数据集。第一步是找到离每个点最近的线。然后,我将比较 points 数据集中的一些属性与lines 数据集,并确认或拒绝连接,就像我提到的那样。
tree_idx:
tree_idx 是使用以下代码创建的:
import rtree
lines_bounds = lines['geometry'].apply(lambda x: x.bounds)
tree_idx = rtree.index.Index()
for i in lines_bounds.index:
tree_idx.insert(i, lines_bounds.loc[i])
【问题讨论】:
-
您能否详细说明您希望拥有但无法通过字典实现的功能?
-
我正在尝试进行空间连接。在这样做的过程中,最接近的并不总是正确的加入伙伴。在确认加入之前,我还需要查看其他参数。所以我的计划是从最近的地方向外移动,边走边检查、确认或拒绝。字典不是结构化的,不能按顺序存储。此外,字典不能按位置索引,而且我无法事先知道所有段的键。
-
您能解释一下为什么在您的情况下使用 pandas Series/DataFrame 不起作用吗?由于 pandas 完全适用于您解释的情况(保持值和标签之间的链接,但仍然能够使用这些值,对它们进行排序,..)
-
此外,也许
geopandas会很有趣:geopandas.readthedocs.io/en/latest/index.html -
@Kartik:听起来你的计算效率很低。我认为我们需要查看整个代码来提供帮助。我认为这是 XY 问题的一个示例,您在其中寻求数据结构帮助,而您的问题可能在您的算法中。