基于1秒时间容差的DataFrame跨表匹配合并需求
按时间容差匹配合并两个DataFrame
前提准备
首先得把两个DataFrame的时间列转成datetime类型,不然没法计算时间差:
import pandas as pd # 批量转换时间列格式 for df in [df1, df2]: df['startTimeIso'] = pd.to_datetime(df['startTimeIso']) df['endTimeIso'] = pd.to_datetime(df['endTimeIso'])
核心匹配合并逻辑
根据数据量大小,有两种实现方式:
方法1:交叉合并+直接筛选(小数据量适用)
先生成两个DataFrame的所有行组合,再筛选符合时间容差的行:
# 交叉合并所有行组合 cross_df = df1.merge(df2, how='cross', suffixes=('_df1', '_df2')) # 筛选startTime和endTime差均在1秒内的记录 matched_df = cross_df[ (abs(cross_df['startTimeIso_df1'] - cross_df['startTimeIso_df2']) <= pd.Timedelta(seconds=1)) & (abs(cross_df['endTimeIso_df1'] - cross_df['endTimeIso_df2']) <= pd.Timedelta(seconds=1)) ] # 整理成目标结构的df_merged df_merged = matched_df[['startTimeIso_df1', 'endTimeIso_df1', 'id', 'value']].rename( columns={'startTimeIso_df1': 'startTimeIso', 'endTimeIso_df1': 'endTimeIso'} ) # 统计匹配行数 match_count = len(df_merged) print(f"匹配行数:{match_count}")
方法2:先范围过滤再匹配(大数据量适用)
如果数据量较大,交叉合并会产生过多临时数据,可先给时间列设定±1秒的区间,缩小匹配范围:
# 给df1的时间列添加容差区间 df1['start_low'] = df1['startTimeIso'] - pd.Timedelta(seconds=1) df1['start_high'] = df1['startTimeIso'] + pd.Timedelta(seconds=1) df1['end_low'] = df1['endTimeIso'] - pd.Timedelta(seconds=1) df1['end_high'] = df1['endTimeIso'] + pd.Timedelta(seconds=1) # 合并后按区间筛选符合条件的行 merged_pre = df1.merge(df2, how='inner', suffixes=('_df1', '_df2')) matched_df = merged_pre[ merged_pre['startTimeIso_df2'].between(merged_pre['start_low'], merged_pre['start_high']) & merged_pre['endTimeIso_df2'].between(merged_pre['end_low'], merged_pre['end_high']) ] # 整理目标结构 df_merged = matched_df[['startTimeIso_df1', 'endTimeIso_df1', 'id', 'value']].rename( columns={'startTimeIso_df1': 'startTimeIso', 'endTimeIso_df1': 'endTimeIso'} ) match_count = len(df_merged) print(f"匹配行数:{match_count}")
补充说明
- 如果存在一行df2匹配多行df1的情况,
df_merged会保留所有符合条件的组合,若需要唯一匹配,可额外添加筛选规则(比如取时间差最小的行)。 - 确保两个DataFrame的时间列时区一致,若有时区差异,需先统一时区再计算。
内容的提问来源于stack exchange,提问作者ranqnova
相关产品推荐
相关产品推荐

