首页 > 解决方案 > 如何矢量化比较来自两个不同数据帧的形状对象的函数?

问题描述

我有一个 pandas 数据框和一个 geopandas 数据框。在 Pandas 数据框中,我有一列Points包含shapely.geometry Point对象。geopandas 框架中的几何列有Polygon对象。我想做的是Point在 Pandas 框架中取一个并测试它是否是geopandas 框架中的within 任何Polygon对象。

在熊猫框架的新列中,我想要以下内容。如果Point在给定的范围内Polygon(即within调用返回True),我希望 ' 行中的新列值是 geopandas 框架Point中 ' 行中不同列的值。Polygon

我对这个问题有一个可行的解决方案,但它不是矢量化的。是否可以对其进行矢量化?

例子:

import geopandas as gpd
import pandas as pd
from shapely.geometry import Point, Polygon

# Create random frame, geometries are supposed to be mutually exclusive
gdf = gpd.GeoDataFrame({'A': [1, 2], 'geometry': [Polygon([(10, 5), (5, 6)]), Polygon([(1,2), (2, 5))]})

# Create random pandas
df = pd.DataFrame({'Foo': ['bar', 'Bar'], 'Points': [Point(4, 5), Point(1, 2)]})

# My non-vectorized solution
df['new'] = ''
for i in df.index:
    for j in gdf.index:
        if df.at[i, 'Points'].within(gdf.at[j, 'geometry']):
            df.at[i, 'new'] = gdf.at[j, 'A'] 

这很好用,因此当点在多边形内时,df['new']它将包含列中的任何内容。gdf['A']我希望有办法让我对这个操作进行矢量化。

标签: pythonpandasvectorizationgeopandasshapely

解决方案


Points您可以计算和的所有点之间的欧几里得距离Polygon。而且,只要距离等于 0,这将为您提供一个交点。我的方法如下。请注意,我把从您的数据帧中获取所有点和多边形点的部分留给您。可能,类似的功能pandas.Series.toList应该提供。

import numpy as np
from scipy.spatial.distance import cdist

polygon = [[10,5],[5,6],[1,2],[2,5]]
points = [[4,5],[1,2]]

# return distances between all the items of the two arrays
distances = cdist(polygon,points) 

print(distances)
[[6.         9.48683298]
 [1.41421356 5.65685425]
 [4.24264069 0.        ]
 [2.         3.16227766]]

我们现在要做的就是获取数组中 0 的索引。如您所见,我们的交点在第 3 行和第 2 列,即多边形的第 3 项或点的第 2 项。


for i,dist in enumerate(distances.flatten()):
    if dist==0:
        intersect_index = np.unravel_index(i,shape=distances.shape)
        intersect_point = polygon[intersect_index[0]]
        print(intersect_point)
[1,2]

这应该为您提供您正在寻找的矢量化形式。


推荐阅读