如何基于另一个DataFrame的日期为DataFrame新增Status列
问题:基于日期区间匹配为DataFrame生成状态列
数据情况
DF1
Date ID --------------------------------------- 12-03-2020 01:10:00 AAA 22-04-2020 02:10:00 BBB 02-02-2020 13:55:00 CCC 15-11-2020 05:20:00 DDD 19-08-2020 14:30:00 EEE 23-04-2020 11:11:00 FFF 30-07-2020 21:40:00 GGG 11-10-2020 01:10:00 HHH 07-03-2020 01:10:00 III 06-01-2020 01:10:00 JJJ
DF2
Start Date End Date ID --------------------------------------------- 12-03-2020 01:00:00 12-03-2020 02:00:00 AAA 22-04-2020 02:00:00 22-04-2020 02:30:00 BBB 02-02-2020 13:00:00 02-02-2020 14:00:00 JJJ 15-11-2020 05:00:00 15-11-2020 05:10:00 DDD 30-07-2020 21:50:00 30-07-2020 21:55:00 EEE
需求说明
需在DF1中生成名为Status的列:
- 当DF1的
Date处于DF2对应ID的Start Date与End Date区间内时,显示Yes - 其余情况显示
No
预期结果:
Fecha y Hora ID Estatus --------------------------------- 12-03-2020 01:10:00 AAA Yes 22-04-2020 02:10:00 BBB Yes 02-02-2020 13:55:00 CCC No 15-11-2020 05:20:00 DDD No 19-08-2020 14:30:00 EEE Yes 23-04-2020 11:11:00 FFF No 30-07-2020 21:40:00 GGG No 11-10-2020 01:10:00 HHH No 07-03-2020 01:10:00 III No 06-01-2020 01:10:00 JJJ No
用户尝试代码
当前代码仅完成了ID匹配,缺少日期区间判断逻辑:
df1["status"] = df1.apply(lambda x: "si" if df2["ID"].isin(x).any() else "no",axis=1)
解决方案
步骤1:统一日期格式为datetime
首先将所有日期列转换为可比较的datetime类型,避免字符串比较误差:
import pandas as pd # 转换DF1日期列 df1['Date'] = pd.to_datetime(df1['Date'], format='%d-%m-%Y %H:%M:%S') # 转换DF2日期列 df2['Start Date'] = pd.to_datetime(df2['Start Date'], format='%d-%m-%Y %H:%M:%S') df2['End Date'] = pd.to_datetime(df2['End Date'], format='%d-%m-%Y %H:%M:%S')
步骤2:关联数据并判断日期区间
方案一:左连接+行判断(适合大数据集)
通过merge按ID关联两个数据集,逐行判断日期是否在区间内:
# 按ID左连接DF1和DF2 merged_df = df1.merge(df2, on='ID', how='left') # 生成Status列:判断日期是否在对应ID的区间内 merged_df['Status'] = merged_df.apply( lambda row: 'Yes' if (pd.notna(row['Start Date']) and row['Start Date'] <= row['Date'] <= row['End Date']) else 'No', axis=1 ) # 保留原DF1的列和新生成的Status列 df1 = merged_df[['Date', 'ID', 'Status']]
方案二:直接apply匹配(适合小数据集)
如果数据量较小,可直接在apply中根据ID筛选DF2的对应行,再判断日期:
df1['Status'] = df1.apply( lambda row: 'Yes' if any( (df2['ID'] == row['ID']) & (df2['Start Date'] <= row['Date']) & (row['Date'] <= df2['End Date']) ) else 'No', axis=1 )
运行上述代码后,DF1将生成符合预期的Status列。
内容的提问来源于stack exchange,提问作者Elthon Daniel Rivas
相关产品推荐
相关产品推荐

