我有两个数据帧,df1 和 df2,我想将其合并到列“id”上,其中 df1 的“触发日期”落在 df2 的“开始日期”和“结束日期”之间,但是,保留没有的行匹配。
df1:
id triggerdate
a 09/01/2022
a 08/15/2022
b 06/25/2022
c 06/30/2022
c 07/01/2022
df2:
id startdate enddate value
a 08/30/2022 09/03/2022 30
b 07/10/2022 07/15/2022 5
c 06/28/2022 07/05/2022 10
预期输出:
id triggerdate startdate enddate value
a 09/01/2022 08/30/2022 09/03/2022 30
a 08/15/2022 NaN NaN NaN
b 06/25/2022 NaN NaN NaN
c 06/30/2022 06/28/2022 07/05/2022 10
c 07/01/2022 06/28/2022 07/05/2022 10
到目前为止我采取的方法是:
df_merged = df1.merge(df2, on = ['id'], how='outer')
output = df_merged.loc[
df_merged['triggerdate'].between(
df_merged['startdate'],
df_merged['enddate'], inclusive='both')]
但是,此方法执行以下操作:1) 将 df1 中的“id”值与 df2 匹配,无论是否满足条件;2) 然后删除不满足条件的所有行。
不幸的是,我没能在网上找到解决方案。
获得预期输出的推荐方法是什么?
试试这个:
idx = pd.IntervalIndex.from_arrays(df2['startdate'],df2['enddate'])
df['value'] = pd.Series(df2['value'].tolist(),index = idx).reindex(df['triggerdate']).tolist()
旧答案:
尝试
pd.merge_asof()
修改 df2 以在日期列上合并
df2 = (pd.concat([df2,
df2[['id','enddate']]
.rename({'enddate':'startdate'},axis=1)]))
然后合并
(pd.merge_asof(df.reset_index().sort_values('triggerdate'),
df2.sort_values('startdate'),
left_on = 'triggerdate',
right_on = 'startdate',
by = 'id')
.sort_values('index')
.drop('index',axis=1))
输出:
id triggerdate startdate enddate value
4 a 2022-09-01 2022-08-30 2022-09-03 30.0
3 a 2022-08-15 NaT NaT NaN
0 b 2022-06-25 NaT NaT NaN
1 c 2022-06-30 2022-06-28 2022-07-05 10.0
2 c 2022-07-01 2022-06-28 2022-07-05 10.0