如何基于列匹配与时间范围实现Pandas DataFrame左连接
实现指定条件的DataFrame左连接
首先需要将所有时间列转换为datetime类型,否则无法进行时间范围判断:
import pandas as pd # 转换时间列格式 period_df['Start time'] = pd.to_datetime(period_df['Start time']) period_df['End time'] = pd.to_datetime(period_df['End time']) records_df['Reference time'] = pd.to_datetime(records_df['Reference time'])
方法一:笛卡尔积合并后过滤(适合小数据集)
先基于Day和Direction做左连接得到所有可能组合,再筛选时间符合条件的记录:
# 按分组列左连接 merged = records_df.merge(period_df, on=['Day', 'Direction'], how='left') # 过滤时间范围匹配的记录 result = merged[(merged['Reference time'] >= merged['Start time']) & (merged['Reference time'] <= merged['End time'])]
方法二:使用merge_asof(适合大数据集,效率更高)
merge_asof是专门针对时间序列匹配的高效方法,需先对时间列排序:
# 对两个数据集按分组列+时间列排序 period_df_sorted = period_df.sort_values(['Day', 'Direction', 'Start time']) records_df_sorted = records_df.sort_values(['Day', 'Direction', 'Reference time']) # 按分组列匹配,同时匹配时间范围 result = pd.merge_asof( records_df_sorted, period_df_sorted, left_on='Reference time', right_on='Start time', by=['Day', 'Direction'], direction='backward', allow_exact_matches=True ) # 补充过滤确保Reference time不超过End time result = result[result['Reference time'] <= result['End time']] # 恢复原records_df的行顺序 result = result.set_index(records_df_sorted.index).sort_index()
最终result会保留records_df的所有行,并匹配到符合条件的period_df中的Period、Start time和End time列。
内容的提问来源于stack exchange,提问作者z star
相关产品推荐
相关产品推荐

