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

如何用Pandas计算两个DataFrame间的最小正时间差

高效匹配DataFrame时间并获取最小正差值及对应站点信息

需求说明

有两个包含时间列的DataFrame:

  • df1包含Stop Time(结束时间)和Site(站点)列
  • df2包含Start Time(开始时间)和Site(站点)列

需要为df2中的每一条记录,计算其Start Time与df1所有Stop Time的正差值(即Start Time > Stop Time),筛选出其中的最小差值,并保留对应的df1的Site信息,最终存入新的df_bestDataFrame。要求用高效的Pandas方法替代循环实现。

示例数据

df1

Stop Time                 Site
 2023-10-17 20:10:00.310      P2
 2023-10-17 21:20:00.440      P1
 2023-10-17 23:30:00.200      P2
 2023-10-18 00:00:00.190      P1
 2023-10-18 01:00:00.130      P1
 2023-10-18 02:00:00.500      P2
 2023-10-18 03:00:00.480      P1
 2023-10-18 04:00:00.020      P2
 2023-10-18 05:00:00.000      P1
 2023-10-18 06:00:00.580      P2

df2

Start Time               Site
2023-10-17 16:00:00.190      SMR
2023-10-17 17:05:00.050      SMR
2023-10-17 19:10:00.550      SMR
2023-10-17 21:40:00.530      SMR
2023-10-17 22:21:00.180      SMR
2023-10-18 05:21:00.090      SMR
2023-10-18 09:15:00.360      SMR
2023-10-18 11:54:00.160      SMR

比如df2中2023-10-17 21:40:00.530这条记录,匹配到df1中最近的Stop Time是2023-10-17 21:20:00.440,差值约20分钟,对应df1的Site为P1。

高效解决方案

使用Pandas的merge_asof方法,该方法专门用于按时间序列匹配最近的记录,效率远高于循环遍历。

步骤1:转换时间格式并排序

merge_asof要求两个DataFrame都按时间列排序,因此先转换时间类型并排序:

import pandas as pd

# 转换时间列为datetime类型
df1['Stop Time'] = pd.to_datetime(df1['Stop Time'])
df2['Start Time'] = pd.to_datetime(df2['Start Time'])

# 按时间列排序
df1_sorted = df1.sort_values('Stop Time').reset_index(drop=True)
df2_sorted = df2.sort_values('Start Time').reset_index(drop=True)

步骤2:时间匹配

使用merge_asof匹配df2每条记录对应的df1中最大的、小于等于当前Start Time的Stop Time(即差值最小的正差值):

df_best = pd.merge_asof(
    df2_sorted,
    df1_sorted,
    left_on='Start Time',
    right_on='Stop Time',
    direction='backward'  # 找小于等于左表时间的最近右表记录
)

步骤3:计算差值并整理结果

计算时间差,过滤无效匹配(若df2的Start Time早于df1所有Stop Time,会得到NaN),并重命名列让结果更清晰:

# 计算时间差值
df_best['Time Difference'] = df_best['Start Time'] - df_best['Stop Time']

# 过滤无有效匹配的行(可选,根据需求调整)
df_best = df_best.dropna(subset=['Time Difference']).reset_index(drop=True)

# 重命名列区分两个DataFrame的Site
df_best = df_best.rename(columns={'Site_x': 'df2_Site', 'Site_y': 'df1_Site'})

结果说明

最终的df_best会包含df2的原始信息、匹配到的df1的Stop Time和Site,以及对应的最小正时间差。以示例中的2023-10-17 21:40:00.530记录为例,会得到:

Start Time df2_Site           Stop Time df1_Site Time Difference
3 2023-10-17 21:40:00.530      SMR 2023-10-17 21:20:00.440      P1        0 days 00:20:00.090000

效率优势

merge_asof基于排序后的线性扫描实现,时间复杂度为O(n log n + m log m)(主要来自排序步骤),相比循环遍历的O(n*m),在数据量较大时性能提升非常明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:57:11