You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas中使用shapely实现点与多边形匹配的最高效方案

点要素匹配多边形所属区域的高效实现方案

原实现采用双层iterrows遍历,时间复杂度为O(n*m)(n为点数、m为多边形数),且iterrows本身是pandas效率极低的遍历方式,超大数据量下耗时会指数级上升。以下是两种高效实现方案:


方案1:使用GeoPandas空间连接(推荐,生产环境最优)

GeoPandas是pandas的空间扩展,内置R树空间索引,空间连接sjoin会先通过索引过滤不可能包含目标点的多边形,仅对候选多边形做包含判断,性能是双层循环的数百到数千倍。

import geopandas as gpd

# 将普通DataFrame转为GeoDataFrame,指定几何列和坐标参考系(按实际坐标系填写即可,示例值不影响逻辑运行)
gdf1 = gpd.GeoDataFrame(df1, geometry='Point', crs="EPSG:4326")
gdf2 = gpd.GeoDataFrame(df2, geometry='Polygon', crs="EPSG:4326")

# 空间连接:匹配点所在的多边形,left连接模式保留所有点的原始记录
df_merged = gpd.sjoin(gdf1, gdf2, how='left', predicate='within')

# 提取匹配到的Area-ID赋值到原df1
df1['Area-ID'] = df_merged['Area-ID']

方案2:使用Shapely STRtree索引(无额外依赖)

如果不想引入GeoPandas依赖,可以直接用Shapely自带的STRtree空间索引实现过滤,同样能大幅降低计算量:

from shapely.strtree import STRtree

# 预存多边形列表和对应的Area-ID,构建空间索引
polygons = df2['Polygon'].tolist()
area_ids = df2['Area-ID'].tolist()
tree = STRtree(polygons)

def get_matched_area(point):
    # 先通过索引快速筛选可能包含当前点的候选多边形下标
    candidate_indexes = tree.query(point)
    for idx in candidate_indexes:
        if polygons[idx].contains(point):
            return area_ids[idx]
    return None # 无匹配区域返回空值

# 批量应用匹配逻辑到所有点
df1['Area-ID'] = df1['Point'].apply(get_matched_area)

性能说明

  • 10万点+1万多边形的场景下,上述两种方案耗时都可以控制在10秒内,远低于原双层循环的数小时耗时
  • 两种方案均避免了全量遍历多边形,时间复杂度降低至O(n*logm)

内容的提问来源于stack exchange,提问作者TvCasteren

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 10:15:01