如何在Python中匹配df1时间处于df2区间的记录并获取位置
解决DataFrame区间匹配问题:根据Person_ID和时间区间关联Location
核心需求
为df1的每条记录,匹配df2中相同Person_ID且Event_DateTime处于Start_Time与End_Time之间的Location字段,最终生成目标DataFrame df3。
前提准备
先确保所有时间字段为datetime类型,否则先转换:
import pandas as pd df1['Event_DateTime'] = pd.to_datetime(df1['Event_DateTime']) df2['Start_Time'] = pd.to_datetime(df2['Start_Time']) df2['End_Time'] = pd.to_datetime(df2['End_Time'])
方法一:Merge + 布尔过滤(简单直接,适配数千行数据)
先按Person_ID合并两个DataFrame,再过滤符合时间区间的行,最后整理结果:
# 按Person_ID合并两表 merged_df = pd.merge(df1, df2, on='Person_ID', how='left') # 过滤时间区间条件 filtered_df = merged_df[(merged_df['Event_DateTime'] >= merged_df['Start_Time']) & (merged_df['Event_DateTime'] <= merged_df['End_Time'])] # 整理为目标df3 df3 = filtered_df[['Person_ID', 'Event_DateTime', 'Location']].reset_index(drop=True)
注:若一个
Event_DateTime匹配到多个Location,会保留所有匹配行;如需唯一结果,可添加drop_duplicates(subset=['Person_ID', 'Event_DateTime'])处理。
方法二:逐行匹配(逻辑灵活,适合需额外处理的场景)
用apply逐行筛选符合条件的记录,逻辑清晰,数千行数据速度可接受:
def get_matched_location(row): # 筛选同ID且时间在区间内的df2行 matched = df2[(df2['Person_ID'] == row['Person_ID']) & (df2['Start_Time'] <= row['Event_DateTime']) & (df2['End_Time'] >= row['Event_DateTime'])] # 返回第一个匹配的Location,无匹配则返回空值 return matched['Location'].iloc[0] if not matched.empty else pd.NA # 生成df3 df3 = df1.copy() df3['Location'] = df3.apply(get_matched_location, axis=1)
方法三:IntervalIndex优化(效率更高,适合数据量偏大的情况)
利用IntervalIndex加速区间匹配,比直接布尔比较更高效:
# 为df2创建时间区间列 df2['Time_Interval'] = pd.IntervalIndex.from_arrays(df2['Start_Time'], df2['End_Time'], closed='both') def find_location(row): # 筛选同ID的分组 group = df2[df2['Person_ID'] == row['Person_ID']] if group.empty: return pd.NA # 查找包含当前Event_DateTime的区间 mask = group['Time_Interval'].contains(row['Event_DateTime']) matched = group[mask] return matched['Location'].iloc[0] if not matched.empty else pd.NA # 生成df3 df3 = df1.copy() df3['Location'] = df3.apply(find_location, axis=1)
内容的提问来源于stack exchange,提问作者wyoming_seth
相关产品推荐
相关产品推荐

