如何在Pandas中拆分重叠日期范围并聚合关联企业?
解决Pandas中重叠日期范围的企业聚合问题
步骤1:数据预处理
首先将字符串格式的日期转换为datetime类型,否则无法进行日期比较和区间判断:
import pandas as pd # 示例数据 df = pd.DataFrame(data={ 'Company':['A','B','C','D','E','F','G'], 'StartDate':['2023-04-01','2023-04-01','2023-04-01','2023-04-01','2023-04-08','2023-04-15','2023-04-20'], 'EndDate':['2023-04-14','2023-05-09','2023-05-09','2023-05-09','2023-04-30','2023-05-18','2023-04-30'] }) # 转换日期列为datetime类型 df['StartDate'] = pd.to_datetime(df['StartDate']) df['EndDate'] = pd.to_datetime(df['EndDate'])
步骤2:合并重叠/连续的日期区间
提取所有唯一的日期区间,排序后合并存在重叠或连续的区间:
# 提取唯一区间并按开始日期排序 unique_intervals = df[['StartDate', 'EndDate']].drop_duplicates().sort_values('StartDate').reset_index(drop=True) # 合并重叠区间 merged_intervals = [] current_start, current_end = unique_intervals.iloc[0][['StartDate', 'EndDate']] for _, row in unique_intervals.iloc[1:].iterrows(): start, end = row['StartDate'], row['EndDate'] # 当前区间与合并区间重叠,更新合并区间的结束日期 if start <= current_end: current_end = max(current_end, end) else: # 无重叠,保存当前合并区间并开启新的合并 merged_intervals.append((current_start, current_end)) current_start, current_end = start, end # 添加最后一个合并区间 merged_intervals.append((current_start, current_end)) # 转换为DataFrame便于后续匹配 merged_df = pd.DataFrame(merged_intervals, columns=['MergedStart', 'MergedEnd'])
步骤3:匹配企业到合并区间并聚合
判断每个企业的日期区间与哪个合并区间重叠,然后按合并区间分组聚合企业列表:
# 匹配企业所属的合并区间 def match_interval(row): for idx, interval in merged_df.iterrows(): # 只要企业区间与合并区间有交集即匹配 if not (row['EndDate'] < interval['MergedStart'] or row['StartDate'] > interval['MergedEnd']): return idx return -1 df['GroupID'] = df.apply(match_interval, axis=1) # 聚合生成结果 result = df.groupby('GroupID').agg( 合并开始日期=('StartDate', lambda x: merged_df.loc[x.name, 'MergedStart']), 合并结束日期=('EndDate', lambda x: merged_df.loc[x.name, 'MergedEnd']), 关联企业=('Company', ', '.join) ).reset_index(drop=True) # 查看结果 print(result)
输出结果
运行上述代码后,输出的结果如下:
合并开始日期 合并结束日期 关联企业 0 2023-04-01 2023-05-09 A, B, C, D, E, G 1 2023-04-15 2023-05-18 F
这个方案可以覆盖完全重叠、部分重叠、区间包含等多种场景,确保所有存在日期交集的企业都被聚合到对应的合并区间中。
内容的提问来源于stack exchange,提问作者PyPyVk
相关产品推荐
相关产品推荐

