如何按时间范围匹配DataFrame?排查合并代码TypeError报错
问题排查与解决方案
错误原因
你遇到的TypeError是因为调用pd.merge()时传入了字典对象,而merge仅接受Series或DataFrame作为合并数据源。这种情况通常是你把时间范围的映射关系做成字典后直接用来合并导致的。
前提准备
先确保两个DataFrame的日期列均为datetime类型:
import pandas as pd # 假设时间范围DataFrame名为range_df,日期DataFrame名为date_df range_df['Start'] = pd.to_datetime(range_df['Start']) range_df['End'] = pd.to_datetime(range_df['End']) date_df['Date'] = pd.to_datetime(date_df['Date'])
正确实现方式
方式1:逐行匹配(通用场景,支持任意时间范围)
定义函数判断日期落在哪个时间区间,再用apply批量处理:
def map_to_week(date): # 筛选包含当前日期的时间区间行 match_row = range_df[(range_df['Start'] <= date) & (range_df['End'] >= date)] return match_row['Weeks'].iloc[0] if not match_row.empty else None # 给日期DataFrame添加Weeks分类列 date_df['Weeks'] = date_df['Date'].apply(map_to_week)
方式2:merge_asof(高效,适合无重叠的有序时间范围)
如果你的时间范围无重叠且Start列有序,用merge_asof性能更优:
# 对两个DataFrame按日期排序 range_df_sorted = range_df.sort_values('Start') date_df_sorted = date_df.sort_values('Date') # 按日期匹配最近的起始时间,同时确保日期不超过区间结束时间 merged = pd.merge_asof( date_df_sorted, range_df_sorted[['Start', 'End', 'Weeks']], left_on='Date', right_on='Start', direction='backward' ) # 过滤超出时间区间的记录,整理结果 final_result = merged[merged['Date'] <= merged['End']].drop(columns=['Start', 'End']) # 恢复原DataFrame的顺序(可选) final_result = final_result.sort_index()
错误代码修正示例
如果你之前的代码是将时间范围转成字典后直接merge,比如:
# 错误代码示例 week_dict = dict(zip(range_df['Start'], range_df['Weeks'])) result = pd.merge(date_df, week_dict, left_on='Date', right_index=True)
需先将字典转成DataFrame,但这种方式仅能匹配日期等于Start的情况,不适合范围匹配,更推荐前面两种通用方法。
内容的提问来源于stack exchange,提问作者CanaryTheBird
相关产品推荐
相关产品推荐

