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

如何在Pandas中对两个DataFrame基于分组列与日期列执行asof merge?

如何使用Pandas的merge_asof实现按水果匹配最接近日期的合并?

需求说明

拥有两个DataFrame(df1和df2),需通过Pandas的merge_asof执行asof合并:

  • 按Frutas列分组,为对应水果匹配最接近的日期/时间
  • 合并df1的Data列与df2的Data/Hora列信息
  • 最终保留Transcricao和Pedido de venda列

DataFrame结构

DataFrame df1

from datetime import datetime
import pandas as pd

datas_df1 = [datetime(2023, 8, 1), datetime(2023, 8, 3), datetime(2023, 8, 2), datetime(2023, 8, 1),
             datetime(2023, 8, 1), datetime(2023, 8, 3), datetime(2023, 8, 4), datetime(2023, 8, 4),
             datetime(2023, 8, 2), datetime(2023, 8, 4)]

df1_dict = {
    "Frutas": ["Maçã", "Banana", "Laranja", "Uva", "Morango", "Pera", "Abacaxi", "Melancia", "Cereja", "Kiwi"],
    "Data": datas_df1,
    "Transcricao": [f"Transcricao_{i}" for i in range(10)]
}

df1 = pd.DataFrame(df1_dict)

DataFrame df2

datas_df2 = [datetime(2023, 8, 1, 14, 37), datetime(2023, 8, 3, 8, 23), datetime(2023, 8, 1, 9, 56),
             datetime(2023, 8, 4, 12, 9), datetime(2023, 8, 3, 10, 50), datetime(2023, 8, 2, 17, 38),
             datetime(2023, 8, 4, 19, 22), datetime(2023, 8, 2, 7, 44), datetime(2023, 8, 1, 21, 33),
             datetime(2023, 8, 2, 23, 6)]

df2_dict = {
    "Frutas": ["Maçã", "Banana", "Laranja", "Uva", "Morango", "Pera", "Abacaxi", "Melancia", "Cereja", "Kiwi"],
    "Data/Hora": datas_df2,
    "Pedido de venda": [f"Pedido_{i}" for i in range(10)]
}

df2 = pd.DataFrame(df2_dict)

错误代码及问题

尝试执行以下代码时出现TypeError: Function call with ambiguous argument types:

df_merge = pd.merge_asof(df1.sort_values('data'), 
                                   df2.sort_values('Data/Hora'), 
                                   left_on='data', 
                                   right_on='Data/Hora',
                                   by='Frutas')

错误原因

  1. 列名大小写错误:df1的时间列是Data(首字母大写),但代码中写成了小写的data,导致无法找到对应列
  2. 排序不完整:merge_asof要求两个DataFrame必须同时按by列(Frutas)和时间列排序,仅排序时间列会导致分组匹配逻辑失效
  3. 时间类型兼容问题:df1的Data是日期类型,df2的Data/Hora是带时分秒的datetime类型,虽可比较,但统一类型能避免潜在问题

正确实现代码

# 1. 统一时间列类型(将df1的Data转为datetime类型)
df1['Data'] = pd.to_datetime(df1['Data'])

# 2. 按分组列+时间列排序(merge_asof强制要求)
df1_sorted = df1.sort_values(by=['Frutas', 'Data'])
df2_sorted = df2.sort_values(by=['Frutas', 'Data/Hora'])

# 3. 执行merge_asof,使用direction='nearest'匹配最接近的时间
df_merge = pd.merge_asof(
    df1_sorted,
    df2_sorted,
    left_on='Data',
    right_on='Data/Hora',
    by='Frutas',
    direction='nearest'
)

# 4. 筛选需要的列
df_merge_final = df_merge[['Frutas', 'Data', 'Transcricao', 'Data/Hora', 'Pedido de venda']]
print(df_merge_final)

代码说明

  • 类型统一:将df1的Data转为datetime类型,确保与df2的Data/Hora类型完全兼容
  • 正确排序:按Frutas(分组依据)和时间列排序,保证merge_asof能按分组匹配时间
  • direction参数:direction='nearest'会为每个df1的记录,找到同水果分组下时间差最小的df2记录,完全符合“匹配最接近日期/时间”的需求(默认direction='backward'仅匹配不大于左边时间的最近记录)
  • 列筛选:最终保留业务需要的列,剔除冗余数据

内容的提问来源于stack exchange,提问作者Guilherme Henrique Favaro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:10:57