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

如何在pandas中按起止时间匹配合并两个DataFrame

实现DataFrame区间匹配合并的方法

前置处理:转换时间格式

首先要把两个DataFrame里的字符串时间转为pandas可比较的datetime类型,同时对匹配列排序:

import pandas as pd

# 示例数据初始化
df1 = pd.DataFrame({"time": ["10:34:10", "10:34:20", "10:34:30", "10:34:40", "10:34:50", "10:35:00", "10:35:10", "10:35:20"]})
df2 = pd.DataFrame({"start_time": ["10:34:10", "10:34:40"], "end_time": ["10:34:20", "10:34:50"], "session_type": ["11v11", "zonal game"]})

# 转换时间格式
df1['time'] = pd.to_datetime(df1['time'])
df2['start_time'] = pd.to_datetime(df2['start_time'])
df2['end_time'] = pd.to_datetime(df2['end_time'])

# 按时间列排序(merge_asof要求必须排序)
df1 = df1.sort_values('time').reset_index(drop=True)
df2 = df2.sort_values('start_time').reset_index(drop=True)

方法1:merge_asof实现(高效,适合非重叠区间场景)

这是性能最优的方案,适合大数据量、会话区间无重叠的场景:

# 匹配每个时间点最近的、小于等于该时间的会话开始时间
df3 = pd.merge_asof(df1, df2, left_on='time', right_on='start_time')

# 过滤掉时间超出会话结束时间的记录,不符合的字段填充空值
match_mask = df3['time'] <= df3['end_time']
df3.loc[~match_mask, ['start_time', 'end_time', 'session_type']] = pd.NA

# 可选:把时间转回字符串格式,和示例输出保持一致
df3['time'] = df3['time'].dt.strftime('%H:%M:%S')
df3['start_time'] = df3['start_time'].dt.strftime('%H:%M:%S').where(match_mask, pd.NA)
df3['end_time'] = df3['end_time'].dt.strftime('%H:%M:%S').where(match_mask, pd.NA)

方法2:IntervalIndex实现(支持重叠区间匹配)

如果存在一个时间点落在多个会话区间的场景,可以用这个方法,会返回所有匹配的会话记录:

# 基于df2的起止时间创建闭区间索引
session_intervals = pd.IntervalIndex.from_arrays(df2['start_time'], df2['end_time'], closed='both')

# 为df1每个时间点匹配对应的区间索引
df1['interval_id'] = df1['time'].apply(lambda x: session_intervals.get_loc(x) if session_intervals.contains(x).any() else -1)

# 关联会话字段,得到最终结果
df3 = df1.merge(df2, left_on='interval_id', right_index=True, how='left').drop(columns='interval_id')

内容的提问来源于stack exchange,提问作者Christian Rønsholt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:06:04