GeoPandas批量判断点是否在多边形内的高效实现方法问询
高效批量实现点与多边形的归属标记
这绝对是空间分析里的高频需求,手动逐个写map函数真的太折磨人了,针对你的30个多边形+10000个点的规模,我推荐两个高效的批量实现方案,比手动操作快N倍:
方案1:利用空间连接(sjoin)+ 透视表(最推荐)
GeoPandas的sjoin是专门优化过的空间匹配工具,处理这类批量归属问题效率极高,步骤如下:
- 先执行空间连接,把每个点和包含它的多边形关联起来
import geopandas as gpd # 空间连接:找到每个点所在的多边形(left连接保留所有点) joined_df = gpd.sjoin(df_points, df_poly, how="left", predicate="within")
predicate="within":明确判断逻辑是“点是否在多边形内”how="left":确保所有原始点都被保留,哪怕不在任何多边形里
- 将连接结果转换为布尔值矩阵
通过透视表把多边形ID转成列,用存在性标记布尔值:
# 生成每个点对应各多边形的布尔值列 poly_indicator = joined_df.pivot_table( index=df_points.index, # 用原始点的索引对齐 columns="id", # 多边形ID作为列名 values="index_right", # 任意存在的列,仅用来判断是否匹配 aggfunc="count", # 匹配到则计数为1,否则为0 fill_value=False # 未匹配的填充为False ).astype(bool) # 把数值转成布尔值
- 合并回原始点数据框
# 把布尔值列合并到原始点GeoDataFrame df_points = df_points.join(poly_indicator)
方案2:向量化空间判断循环(更简洁)
如果觉得透视表有点绕,也可以直接遍历多边形,用GeoPandas的向量化空间方法批量生成列:
# 遍历每个多边形,批量添加归属列 for poly_name, poly_geom in df_poly.set_index("id")["geometry"].items(): # 向量化判断:所有点是否在当前多边形内 df_points[poly_name] = df_points["points"].within(poly_geom)
这里的within是GeoPandas的向量化方法,比你手动写的lambda+map快得多,因为它是底层优化过的批量操作,不需要逐行处理每个点。
注意事项
- 坐标系一致性:一定要确保
df_poly和df_points的坐标系(CRS)完全一致,否则空间判断会出错!可以用df_poly.crs和df_points.crs检查,不一致的话用df_points = df_points.to_crs(df_poly.crs)转换。 - 性能对比:对于你的数据规模,两个方案都能很快完成,但
sjoin方案在多边形/点数量更大时(比如上百个多边形、十万级点)性能优势更明显。
内容的提问来源于stack exchange,提问作者Kvothe




