【发布时间】:2021-08-12 16:46:06
【问题描述】:
我希望这里有人可以帮助我。我已经尝试了几乎所有我能想到的网络搜索,但我似乎无法找到可以帮助我获得所需内容的信息。
我有几个数据集,其中客户服务期是连续或重叠的,类似于下面。
import pandas as pd
cust = ['CUST123', 'CUST123', 'CUST123', 'CUST123', 'CUST456', 'CUST456']
start_date = ['01/01/2021','01/07/2021','01/15/2021','02/02/2021','01/05/2021','01/16/2021']
end_date = ['01/11/2021','01/14/2021','01/31/2021','02/28/2021','01/15/2021','01/31/2021']
df = pd.DataFrame(list(zip(cust, start_date, end_date)), columns = ['cust', 'start_date', 'end_date'])
df['start_date'] = pd.to_datetime(df['start_date'])
df['end_date'] = pd.to_datetime(df['end_date'])
我需要做的是折叠重叠或连续的日期范围,以便之后我只剩下连续的服务期:
我有一个 SAS 程序可以做到这一点,并且在过去 10 年左右为我提供了良好的服务,但遗憾的是,我的公司将在 2022 年底放弃 SAS 转而使用 Python,而我之前正争先恐后地移植多年的 SAS 代码那么。
SAS 程序甚至可以设置一个变量来确定结束日期和开始日期之间可以存在多少时间(以天为单位),以便被认为是连续的。因此,例如,使用上面的示例,如果我将变量设置为 2,则 CUST123 将只有 1 个输出行,因为 2/2/21 在 21/1/31 的 2 天内。
此时,任何帮助或指导都会被欣然接受。我现在很迷茫。
更新:
我非常接近,但我似乎无法完全到达那里。 鉴于下面的原始数据框,我将共享的原始代码修改为:
df.groupby(["cust","service_tier"], as_index=False).apply(
lambda d: d.sort_values(["cust", "service_tier", "start_date", "end_date"])
.groupby(
["cust", "service_tier", (~(d["start_date"] <= (d["end_date"].shift() + pd.Timedelta(days=3)))).cumsum()],
as_index=False
)
.agg({"start_date": "min", "end_date": "max"})
).reset_index(drop=True)
原始数据帧:
cust service_tier start_date end_date
0 CUST123 1 2020-06-13 2020-06-27
1 CUST123 1 2020-06-15 2020-07-13
2 CUST123 1 2020-06-22 2020-07-23
3 CUST123 1 2020-06-24 2020-07-08
4 CUST123 1 2020-07-13 2020-07-27
5 CUST123 1 2020-08-20 2020-09-17
6 CUST123 1 2020-08-21 2020-09-04
7 CUST123 1 2020-08-25 2020-09-05
8 CUST123 1 2020-08-27 2020-09-21
9 CUST123 1 2020-09-01 2020-10-05
10 CUST123 1 2020-09-10 2020-09-17
11 CUST123 1 2020-10-05 2020-11-30
12 CUST123 1 2020-12-01 2021-05-31
13 CUST123 1 2021-06-01 2021-11-30
14 CUST456 1 2021-01-05 2021-01-15
15 CUST456 2 2021-01-16 2021-01-31
修改后的代码让我明白了:
cust service_tier start_date end_date
0 CUST123 1 2020-06-13 2020-07-23
1 CUST123 1 2020-07-13 2020-07-27
2 CUST123 1 2020-08-20 2020-10-05
3 CUST123 1 2020-10-05 2021-11-30
4 CUST456 1 2021-01-05 2021-01-15
5 CUST456 2 2021-01-16 2021-01-31
什么时候真的应该是这样的:
cust service_tier start_date end_date
0 CUST123 1 2020-06-13 2020-07-27
1 CUST123 1 2020-08-20 2021-11-30
2 CUST456 1 2021-01-05 2021-01-15
3 CUST456 2 2021-01-16 2021-01-31
我认为这是因为代码没有考虑到日期范围是否完全包含在先前的日期范围内。 我一直在试图弄清楚如何更新 "(~(d["start_date"] ”部分有多个条件,但我失败得很惨。
【问题讨论】:
标签: python python-3.x pandas dataframe