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

Pandas基于最近时间戳合并两DataFrame并保留重复行问题

pd.merge_asof默认仅会为左表每行匹配右表的第一个符合条件的行,无法拿到右表同一匹配时间戳下的全部数据。我们可以拆分两步实现需求:先为df2每行匹配到df1中最近的时间戳值,再用该值做等值左连接获取df1同时间下的所有行,全程保留df2全量数据。


步骤1:预处理数据(必须)

merge_asof要求参与合并的表按时间戳排序,且时间列需要为datetime类型:

import pandas as pd

# 构造示例数据
df1 =  pd.DataFrame({'tstamp': ['12-11-2021 00:00:00','12-11-2021 00:00:00','12-11-2021 01:00:00','12-11-2021 01:00:00'],'band_name': ['A','B','A','B'],'band_values' : [1,2,3,4]})
df2 = pd.DataFrame({'tstamp': ['12-11-2021 00:10:00','12-11-2021 00:20:00','12-11-2021 01:10:00','12-11-2021 01:20:00','12-11-2021 01:30:00'],'mgr_name': ['John','Nick','Jack','Jayce','Mark'],'mgr_surname': ['Hanks','Lad','Ors','Lancelot','Larks']})

# 转换时间列格式
df1['tstamp'] = pd.to_datetime(df1['tstamp'], format='%d-%m-%Y %H:%M:%S')
df2['tstamp'] = pd.to_datetime(df2['tstamp'], format='%d-%m-%Y %H:%M:%S')

# 按时间戳排序
df1 = df1.sort_values('tstamp').reset_index(drop=True)
df2 = df2.sort_values('tstamp').reset_index(drop=True)

步骤2:为df2每行匹配最近的df1时间戳

# 仅用df1的唯一时间戳做匹配,避免冗余计算
df2_matched = pd.merge_asof(
    df2,
    df1[['tstamp']].drop_duplicates(),
    on='tstamp',
    direction='nearest',
    suffixes=('', '_df1')
).rename(columns={'tstamp_df1': 'matched_df1_tstamp'})

如果需要限制最大匹配时间差,可以增加tolerance参数,比如设置30分钟内才匹配:
pd.merge_asof(..., tolerance=pd.Timedelta(minutes=30))

步骤3:等值关联获取df1全部匹配行

用左连接保证df2全量数据被保留:

final_df = pd.merge(
    df2_matched,
    df1,
    left_on='matched_df1_tstamp',
    right_on='tstamp',
    how='left',
    suffixes=('', '_df1')
)

# 可选:删除冗余的重复时间列
final_df = final_df.drop(columns=['tstamp_df1', 'matched_df1_tstamp'])

结果说明

最终输出共10行,df2的5行数据全部保留,每行都关联了df1对应最近时间戳下的2条(A、B频段)数据,符合需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 00:36:01