多时间序列中重复价格连续时段统计(忽略周末)
识别忽略周末的产品价格连续时段解决方案
核心思路
- 按产品ID和日期排序,保证数据时序正确
- 判定相邻日期的连续性:将周五到周一视为连续日,其他日期以上一个工作日是否等于当前日期为标准
- 基于ID、价格和日期连续性生成分组标签,聚合得到连续时段的统计结果
完整代码实现
import pandas as pd from pandas.tseries.offsets import BDay # 模拟原始数据集 data = { 'ID': [1,1,1,1,1,2,2,2,2,2], 'Date': ['2024-02-01','2024-02-04','2024-02-05','2024-02-06','2024-02-07', '2024-02-01','2024-02-04','2024-02-05','2024-02-06','2024-02-07'], 'Price': ['1,00','1,00','1,20','1,30','1,30','1,30','0,90','0,90','0,90','1,30'] } df = pd.DataFrame(data) # 数据预处理 df['Date'] = pd.to_datetime(df['Date']) df['Price'] = df['Price'].str.replace(',', '.').astype(float) df = df.sort_values(['ID', 'Date']).reset_index(drop=True) # 标记相邻日期是否连续 df['prev_date'] = df.groupby('ID')['Date'].shift(1) df['is_continuous'] = (df['Date'] == df['prev_date'] + BDay(1)) | \ ((df['prev_date'].dt.weekday == 4) & (df['Date'].dt.weekday == 0)) # 生成分组键:ID变更、价格变更或日期不连续时,开启新分组 df['group'] = ( (df['ID'] != df['ID'].shift(1)) | (df['Price'] != df['Price'].shift(1)) | (~df['is_continuous']) ).cumsum() # 聚合计算结果 result = df.groupby(['ID', 'group', 'Price']).agg( start_date=('Date', 'min'), end_date=('Date', 'max'), repeated_days_count=('Date', 'count') ).reset_index().drop('group', axis=1) # 恢复价格的逗号分隔格式 result['Price'] = result['Price'].apply(lambda x: f"{x:.2f}".replace('.', ',')) # 调整列顺序为期望格式 result = result[['ID', 'start_date', 'end_date', 'Price', 'repeated_days_count']] print(result)
关键步骤说明
- 预处理:统一日期和价格的数据格式,排序保证时序正确,避免后续计算出错
- 连续性判断:利用
BDay()工具类判断工作日连续性,同时单独处理周五到周一的跨周末场景 - 分组逻辑:通过布尔值累加生成分组键,确保同一ID下、相同价格且连续的日期被归为一组,完全区分不同ID和非连续的相同价格
- 聚合输出:按分组统计起止日期、价格和天数,最后还原价格格式匹配期望输出
内容的提问来源于stack exchange,提问作者Milena Bär
相关产品推荐
相关产品推荐

