我是python的新手,我不知道如何实现我想要做的事情。我有两个panda数据帧,我需要将它们组合起来。一个数据帧称为'cust'
,另一个称为'items'
。下面是创建两个数据集的代码:
import pandas as pd
cust = {'id': [212175, 286170, 361739, 297438, 415712],
'date_start': ['20/05/2022', '18/05/2022', '10/08/2021', '20/01/2022', '30/07/2021']}
items = {'id': [212175, 212175, 212175, 212175, 212175, 286170, 286170, 286170, 286170, 286170],
'item': ['PX002','PY005','PX003','PX003','NX002','PX002','PY005','PX003','PX003','NX002'],
'date_sent': ['21/05/2022','10/05/2022','01/06/2022','01/07/2021','15/08/2022','19/05/2022','10/07/2022','15/07/2022','10/04/2022','15/06/2022']}
# Create DataFrame
cust_df = pd.DataFrame(cust)
items_df = pd.DataFrame(items)
Cust_df:
id date_start
212175 20/05/2022
286170 18/05/2022
361739 10/08/2021
297438 20/01/2022
415712 30/07/2021
items_df:
id item date_sent
212175 PX002 21/05/2022
212175 PY005 10/05/2022
212175 PX003 01/06/2022
212175 PX003 01/07/2021
212175 NX002 15/08/2022
286170 PX002 19/05/2022
286170 PY005 10/07/2022
286170 PX003 15/07/2022
286170 PX003 10/04/2022
286170 NX002 15/06/2022
我需要找出在两个日期之间发给每位客户的所有物品。每个客户的开始日期不同,应取自cust_df数据帧中的date_start字段。每个客户的结束日期都是相同的,即'12/08/2022'
。因此,客户212175
的日期范围将是20/05/2022 - 12/08/2022
,我需要找出在这些日期之间发送给该客户的所有项目。我想要的输出数据帧应该如下所示:
Output_dataframe:
id item date_sent date_start
212175 PX002 21/05/2022 20/05/2022
212175 PX003 01/06/2022 20/05/2022
286170 PX002 19/05/2022 18/05/2022
286170 PY005 10/07/2022 18/05/2022
286170 PX003 15/07/2022 18/05/2022
286170 NX002 15/06/2022 18/05/2022
在输出表中,我们可以看到对于ID = 212175
,只有3个项目显示。这是因为在窗口20/05/2022 - 12/08/2022
期间只发送了3个项目。
对于ID = 286170
,只有1个项目'PX003'
没有显示在所需的输出中,这是因为该项目的发送日期是在'10/04/2022'
,即客户286170
的date_start (18/05/2022)
之前。
感谢您的帮助。感谢
IIUC,使用merge_asof
:
cust_df['date_start'] = pd.to_datetime(cust_df['date_start'], dayfirst=True)
items_df['date_sent'] = pd.to_datetime(items_df['date_sent'], dayfirst=True)
out = (pd
.merge_asof(items_df.sort_values(by='date_sent'),
cust_df.sort_values(by='date_start'),
by='id', left_on='date_sent', right_on='date_start')
.dropna(subset='date_start')
.loc[lambda d: d['date_sent'] < pd.Timestamp("2022-08-12")]
.sort_values(by=['id', 'item']) # optional
)
输出:
id item date_sent date_start
9 212175 NX002 2022-08-15 2022-05-20
4 212175 PX002 2022-05-21 2022-05-20
5 212175 PX003 2022-06-01 2022-05-20
6 286170 NX002 2022-06-15 2022-05-18
3 286170 PX002 2022-05-19 2022-05-18
8 286170 PX003 2022-07-15 2022-05-18
7 286170 PY005 2022-07-10 2022-05-18
合并并过滤
m = pd.merge(items_df, cust_df, how='inner', on='id')
m.date_start = pd.to_datetime(m.date_start, dayfirst=True)
m.date_sent = pd.to_datetime(m.date_sent, dayfirst=True)
m.loc[ (m.date_start < m.date_sent) * ( m.date_sent < pd.to_datetime("12/08/2022", dayfirst=True))].reset_index()
# id item date_sent date_start
#0 212175 PX002 2022-05-21 2022-05-20
#1 212175 PX003 2022-06-01 2022-05-20
#2 286170 PX002 2022-05-19 2022-05-18
#3 286170 PY005 2022-07-10 2022-05-18
#4 286170 PX003 2022-07-15 2022-05-18
#5 286170 NX002 2022-06-15 2022-05-18