基于Geopandas缓冲区实现两个DataFrame按分钟级100米半径关联
双DataFrame时空关联合并实现方案
前置预处理要求
- 统一时间格式:将两个DataFrame的
Timestamp列统一转为datetime类型,若原始时间带秒级精度,可先通过dt.floor('min')生成分钟级时间列用于分组,确保时间匹配精度为1分钟 - 转换空间坐标系:将两个DataFrame转为GeoDataFrame,先用经纬度初始化WGS84坐标系(EPSG:4326),再转换为单位为米的投影坐标系(如对应区域的UTM投影),否则100米缓冲计算会出现偏差
import geopandas as gpd import pandas as pd from shapely.geometry import Point # 预处理df1 df1['Timestamp'] = pd.to_datetime(df1['Timestamp']) df1['geometry'] = df1.apply(lambda x: Point(x['Lon'], x['Lat']), axis=1) gdf1 = gpd.GeoDataFrame(df1, crs="EPSG:4326") # 替换为你数据所在区域对应的UTM投影EPSG编码,保证距离单位为米 gdf1_proj = gdf1.to_crs(epsg=32631) # 预处理df2 操作和df1完全一致 df2['Timestamp'] = pd.to_datetime(df2['Timestamp']) df2['geometry'] = df2.apply(lambda x: Point(x['Lon'], x['Lat']), axis=1) gdf2 = gpd.GeoDataFrame(df2, crs="EPSG:4326") gdf2_proj = gdf2.to_crs(epsg=32631)
核心关联逻辑
原来的单DF逻辑是用同一个分组的数据做缓冲和匹配,双DF只需调整为:按同一时间分组后,取df2的当前时间分组做缓冲,和df1的当前时间分组做空间连接即可。
# 存储最终匹配结果 result_list = [] # 按时间分组遍历df1 for time_val, gdf1_group in gdf1_proj.groupby('Timestamp'): # 取出df2中对应同一时间的分组 gdf2_group = gdf2_proj[gdf2_proj['Timestamp'] == time_val].copy() if len(gdf2_group) == 0: continue # df2无对应时间数据直接跳过 # 为df2当前分组的点生成100米缓冲区 gdf2_group['geometry'] = gdf2_group.geometry.buffer(100) # 空间连接:df1的点落在df2的100米缓冲区内即为匹配,字段重名自动加后缀区分 match_res = gpd.sjoin(gdf1_group, gdf2_group, op='within', suffixes=('_df1', '_df2')) result_list.append(match_res) # 合并所有时间分组的匹配结果 final_result = pd.concat(result_list, ignore_index=True)
可选优化建议
- 数据量较大时,可以提前给
gdf2_proj的Timestamp字段建索引,加快分组筛选速度 - 空间连接前可以利用GeoDataFrame的空间索引
sindex先做粗过滤,减少精确匹配的计算量
内容的提问来源于stack exchange,提问作者rv1994
相关产品推荐
相关产品推荐

