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

如何简化基于merge_asof的DataFrame时间向前匹配合并操作?

问题描述

我有两个DataFrame,定义如下:

import datetime
import pandas as pd

time_start = datetime.datetime.strptime('2024-02-01 10:00:00', "%Y-%m-%d %H:%M:%S")
interval_l = [1, 7, 14, 17, 21, 22, 31]
df_l = pd.DataFrame(index = [time_start + datetime.timedelta(seconds=i) for i in interval_l])
df_r = pd.DataFrame(range(4), index = [time_start + datetime.timedelta(seconds=10*i) for i in range(4)], columns=['val'])
df_l.index.name = 'datetime'
df_r.index.name = 'datetime'

其中df_r是每10秒一条数据,包含val列。我需要将df_r按最近的向前时间合并到df_l中,未匹配到的时间对应值保留NaN。

目前我通过两次调用merge_asof实现了需求,代码如下:

df_l['time'] = df_l.index
df_r = pd.merge_asof(
    df_r,
    df_l[['time']],
    left_index=True,
    right_index=True,
    direction='forward',
    )
df_l = pd.merge_asof(
    df_l,
    df_r[['time', 'val']],
    left_index=True,
    right_index=True,
    direction='backward',
    by='time'
    )
df_l.drop(columns=['time'], inplace=True)

请问是否有更简洁的实现方式?比如直接用一次merge_asof完成?


简洁实现方案

完全可以通过单次merge_asof调用实现需求,核心是利用direction='forward'的特性,无需构造中间列:

df_l = (df_l.reset_index()
         .merge_asof(df_r.reset_index(), on='datetime', direction='forward')
         .set_index('datetime'))

原理说明

  • merge_asof的direction='forward'会为左表(df_l)的每一行,找到右表(df_r)中大于等于当前行时间的最早匹配项,正好符合“最近的向前时间”的需求;
  • 先通过reset_index()将索引转为列,方便指定on='datetime'进行时间匹配;
  • 最后用set_index恢复原索引,直接得到目标结果。

验证结果和原有代码输出完全一致:

datetimeval
2024-02-01 10:00:010.0
2024-02-01 10:00:070.0
2024-02-01 10:00:141.0
2024-02-01 10:00:171.0
2024-02-01 10:00:212.0
2024-02-01 10:00:222.0
2024-02-01 10:00:313.0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 04:47:20