Pandas merge_asof按容差匹配XY坐标合并求和VAL问题
坐标容差匹配实现方案
问题说明
- 现有两个pandas DataFrame,需基于
X、Y坐标字段关联行,匹配规则为坐标差值在指定容差范围内即判定匹配成功 - 匹配成功后,需将df2对应行的
VAL字段值累加至df1匹配行的VAL字段 - 原代码使用
pd.merge_asof未得到预期结果,测试代码如下:
import pandas as pd d1 = [ ['wp1',0.0,0.0,10],['wp2',10.0,10.0,5],['wp3',7.0,7.0,5]] d2 = [ ['wp4',0.1,0.1,5],['wp5',10.2,10.2,8]] headers = ['Name','X','Y','VAL'] df1 = pd.DataFrame(d1,columns = headers) df2 = pd.DataFrame(d2,columns = headers) # 原错误实现 df3 = pd.merge_asof(df1.sort_values('VAL'), df2.sort_values('VAL'),on=['VAL'],by=['X','Y'],direction='nearest',tolerance=1) # 预期输出 d1_final = [ ['wp1',0.0,0.0,10+5],['wp2',10.0,10.0,5+8]] df1_final = pd.DataFrame(d1_final,columns = headers)
预期输出仅保留匹配成功的行,匹配行的
VAL为两个数据集对应值之和。
原代码失效原因
pd.merge_asof本身不支持二维坐标的联合容差匹配,参数传参逻辑完全不符合需求:
on参数仅支持传入单个有序数值列做近似匹配,传入VAL相当于把VAL作为近似匹配的判断键by参数传入的列要求值完全相等才会进入匹配逻辑,传入X、Y相当于要求两个表的X、Y值精确相等才匹配,和容差匹配规则完全相反,自然无法得到正确结果。
正确实现代码
二维坐标容差匹配最高效的方案是用KDTree做近邻查询,依赖scipy库(pandas常规安装环境一般已自带),代码可直接运行得到预期结果:
from scipy.spatial import KDTree # 自定义坐标容差阈值,可根据业务需求调整 match_tolerance = 0.3 # 基于df2的X、Y坐标构建KDTree索引 coord_tree = KDTree(df2[["X", "Y"]].values) # 遍历df1的所有坐标点,查询df2中距离最近的点,返回两点距离和对应df2的行索引 dist, df2_match_idx = coord_tree.query(df1[["X", "Y"]].values, k=1) # 筛选出距离小于容差的匹配行 match_flag = dist <= match_tolerance res_df = df1[match_flag].copy() # 将匹配到的df2的VAL值累加到df1对应行 res_df["VAL"] += df2.iloc[df2_match_idx[match_flag]]["VAL"].values # 重置索引后即为预期的df1_final res_df = res_df.reset_index(drop=True)
运行后res_df输出如下,和预期结果完全一致:
Name X Y VAL 0 wp1 0.0 0.0 15 1 wp2 10.0 10.0 13
如果需要保留未匹配到的行(比如示例中的wp3),只需要在累加时对未匹配行保留原VAL值即可,不需要额外做过滤。
内容的提问来源于stack exchange,提问作者ShadowMan
相关产品推荐
相关产品推荐

