Pandas:根据条件合并数据帧但保留 NaN

问题描述 投票:0回答:1

我有两个数据帧,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) 然后删除不满足条件的所有行。

不幸的是,我没能在网上找到解决方案。

获得预期输出的推荐方法是什么?

python pandas dataframe
1个回答
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
© www.soinside.com 2019 - 2024. All rights reserved.