Python按几何条件合并点面GeoDataFrame的高效实现方法
高效实现点面空间匹配方案
你可以直接使用GeoPandas内置的空间连接sjoin实现该需求,该方法底层基于R树空间索引优化,5万点+5万面的匹配量级仅需数秒即可完成,无需手动逐行判断几何关系。
实现步骤
- 首先确认两个GeoDataFrame坐标系完全一致,避免几何匹配错误
- 调用
gpd.sjoin做左连接,保留所有点要素记录,匹配条件设置为点在面内 - 按点的唯一标识分组,将匹配到的多面字段聚合为列表格式
完整示例代码
import geopandas as gpd from shapely.geometry import Point, Polygon # 示例数据构造 _polygons = [ Polygon([(5, 5), (5, 13), (13, 13), (13, 5)]), Polygon([(10, 10), (10, 15), (15, 15), (15, 10)]) ] _pnts = [Point(3, 3), Point(8, 8), Point(11, 11)] df_polygons = gpd.GeoDataFrame(geometry=_polygons, index=['foo', 'bar']).reset_index() df_points = gpd.GeoDataFrame(geometry=_pnts, index=['A', 'B', 'C']).reset_index() # 1. 空间左连接,保留所有点记录,匹配条件为点在面内 joined = gpd.sjoin( df_points, df_polygons, how='left', predicate='within', lsuffix='_points', rsuffix='_polygons' ) # 2. 按点的唯一标识分组,聚合匹配到的多面数据为列表 result = joined.groupby('index_points', as_index=False).agg( geometry_points=('geometry', 'first'), geometry_index=('index_polygons', lambda x: x.dropna().tolist()), geometry_polygons=('geometry_polygons', lambda x: x.dropna().tolist()) ).rename(columns={'index_points': 'index'}) # 输出结果验证 print(result)
性能优化建议
- 建议使用GeoPandas 1.0+版本,搭配Shapely 2.0的向量化几何操作,性能比旧版本提升3-10倍
- 若无需保留面要素的所有字段,可提前对
df_polygons做字段裁剪,仅保留需要关联的字段+几何列,减少内存开销 - 坐标系一致的前提下无需手动创建空间索引,
sjoin会自动为面要素构建R树索引加速匹配
内容的提问来源于stack exchange,提问作者jjdblast
相关产品推荐
相关产品推荐

