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

如何按条件匹配两个不同大小的DataFrame

问题描述

现有两个不同大小的DataFrame:
df1:

Miles   AB  Param1  Param2  Param3  Param4
1.5 A   0.12345 0.12345 0.12345 0.12345
1.7 B   0.12345 0.12345 0.12345 0.12345
1.9 A   0.12345 0.12345 0.12345 0.12345
2.6 A   0.12345 0.12345 0.12345 0.12345
2.7 B   0.12345 0.12345 0.12345 0.12345
3.5 B   0.12345 0.12345 0.12345 0.12345
5.6 A   0.12345 0.12345 0.12345 0.12345
7.8 B   0.12345 0.12345 0.12345 0.12345
9.9 B   0.12345 0.12345 0.12345 0.12345

df2:

Miles   AB  Param5
1.9 A   56
2.5 A   69
3.4 B   42
5.6 A   41

需要将df2的Param5字段匹配到df1中,匹配条件:

  • AB字段值相同
  • 两个DataFrame的Miles差值绝对值≤0.1

期望结果:

Miles   AB  Param1  Param2  Param3  Param4  Param5
1.5 A   0.12345 0.12345 0.12345 0.12345 
1.7 B   0.12345 0.12345 0.12345 0.12345 
1.9 A   0.12345 0.12345 0.12345 0.12345 56
2.6 A   0.12345 0.12345 0.12345 0.12345 69
2.7 B   0.12345 0.12345 0.12345 0.12345 
3.5 B   0.12345 0.12345 0.12345 0.12345 42
5.6 A   0.12345 0.12345 0.12345 0.12345 41
7.8 B   0.12345 0.12345 0.12345 0.12345 
9.9 B   0.12345 0.12345 0.12345 0.12345 

尝试用np.where实现时报错:

df1['Param5'] = np.where(((df2['AB']==df1['AB']) & (abs(df2['Miles']-df1['Miles'])<=0.1)), df2['Param5'],'')

错误信息:

ValueError: Can only compare identically-labeled Series objects
解决方案

因为两个DataFrame行数不同,直接按位置对比不可行,推荐两种实现方法:

方法一:使用merge_asof(高效,适合大数据集)

merge_asof支持按分组键匹配后,根据数值列的接近度完成关联,刚好适配需求:

import pandas as pd

# 先按AB分组、Miles排序(merge_asof要求左右DataFrame按on列排序)
df1_sorted = df1.sort_values(['AB', 'Miles'])
df2_sorted = df2.sort_values(['AB', 'Miles'])

# 执行匹配:按AB分组,匹配Miles差值≤0.1的记录
result = pd.merge_asof(
    df1_sorted,
    df2_sorted,
    on='Miles',
    by='AB',
    tolerance=0.1,
    direction='nearest'  # 取最接近的匹配项
)

# 恢复原df1的顺序
result = result.loc[df1.index]
# 将空值替换为空字符串(按需调整)
result['Param5'] = result['Param5'].fillna('')

方法二:使用apply遍历(直观,适合小数据集)

对df1的每一行,在df2中筛选符合条件的记录并提取Param5:

import pandas as pd

def get_param5(row):
    # 筛选AB相同且Miles差值≤0.1的df2记录
    matches = df2[(df2['AB'] == row['AB']) & (abs(df2['Miles'] - row['Miles']) <= 0.1)]
    # 有匹配项则取第一个的Param5,否则返回空字符串
    return matches['Param5'].iloc[0] if not matches.empty else ''

df1['Param5'] = df1.apply(get_param5, axis=1)

两种方法都能得到目标结果,merge_asof性能更优,适合数据量大的场景;apply写法更直观,适合小数据集。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:55:33