GeoPandas空间连接无匹配行问题求助
问题原因及解决方法
核心问题1:CRS设置错误
你创建GeoDataFrame时,用的是**WGS84经纬度(EPSG:4326)**生成的点,但直接用set_crs("ESRI:102003")给几何数据指定投影CRS,这是错误操作:
set_crs的作用是声明现有几何数据的CRS,不是转换坐标。正确流程是先声明原始点的CRS为4326,再用to_crs转换到目标投影CRS。
核心问题2:空间连接参数不合理
针对sjoin_nearest:
你设置的max_distance=0.001(单位米)过小,实际你的点之间的距离远大于这个值(比如gdf1的id=1和gdf2的val=b的点,实际距离约10米左右),导致无匹配结果。
针对sjoin的intersects谓词:
两个点只有完全重合才会满足intersects,你的点坐标存在细微小数位差异,因此不可能匹配。
修正后的代码
方法1:正确转换CRS后使用sjoin_nearest
import pandas as pd import geopandas as gpd df1 = pd.DataFrame({ 'id': [0, 1, 2], 'Lat': [41.8896878, 41.8854416, 33.155480], 'Long': [-87.6188015, -87.615478, -96.731630] }) # 先声明原始点CRS为EPSG:4326,再转换到ESRI:102003 gdf1 = gpd.GeoDataFrame(df1, geometry=gpd.points_from_xy(df1.Long, df1.Lat), crs="EPSG:4326") gdf1 = gdf1.to_crs("ESRI:102003") df2 = pd.DataFrame({ 'val': ['a', 'b', 'c'], 'Lat': [41.88545, 41.885507, 33.15549], 'Long': [-87.61762, -87.615377, -96.73164] }) # 同样正确处理CRS gdf2 = gpd.GeoDataFrame(df2, geometry=gpd.points_from_xy(df2.Long, df2.Lat), crs="EPSG:4326") gdf2 = gdf2.to_crs("ESRI:102003") # 调整max_distance为合理值,比如20米 joined_gdf = gpd.sjoin_nearest( gdf1, gdf2, how='left', max_distance=20, # 单位:米 distance_col="distances" )
方法2:用sjoin配合缓冲实现匹配
如果想用sjoin,可以给gdf1的点创建缓冲区域,再用contains谓词匹配:
# 先正确设置并转换CRS(同方法1) gdf1 = gpd.GeoDataFrame(df1, geometry=gpd.points_from_xy(df1.Long, df1.Lat), crs="EPSG:4326") gdf1 = gdf1.to_crs("ESRI:102003") gdf2 = gpd.GeoDataFrame(df2, geometry=gpd.points_from_xy(df2.Long, df2.Lat), crs="EPSG:4326") gdf2 = gdf2.to_crs("ESRI:102003") # 给gdf1的点创建20米缓冲 gdf1['buffer'] = gdf1.geometry.buffer(20) gdf1 = gdf1.set_geometry('buffer') # 空间连接,用contains谓词 joined_gdf = gpd.sjoin( gdf1, gdf2, predicate='contains', how='left' ) # 恢复原始点几何 joined_gdf = joined_gdf.set_geometry('geometry')
验证结果
修正后,你会看到:
- id=1的点匹配到val=b的记录
- id=2的点匹配到val=c的记录
- id=0的点因距离gdf2所有点超过20米,会保留NaN(可按需调大
max_distance或缓冲半径)
内容的提问来源于stack exchange,提问作者kms
相关产品推荐
相关产品推荐

