不使用pandas实现按连续日期分组统计id的连续达标天数
无pandas依赖的连续达标日期分组统计实现
原pandas代码问题说明
你之前的pandas实现没有按id隔离累加逻辑,cumsum操作是全局生效的,所以跨id的分组会出错。如果要修复pandas版本可以把分组逻辑改为:
s = data.groupby('id')['date'].apply(lambda x: x.diff().dt.days.ne(1).cumsum())
原生Python实现方案
核心逻辑
- 先过滤所有
sales>100的有效记录 - 按id分组,同id的日期转换为标准日期格式后升序排序
- 遍历每个id的排序后日期列表,相邻日期间隔为1天则归为同一连续组,间隔超过1天则拆分新组,每组长度即为连续天数
count
完整代码实现
from collections import defaultdict from datetime import datetime # 假设原始数据为字典组成的列表,格式示例:[{'date':'2024-01-01', 'id':'03', 'sales':120}, ...] raw_data = [] # 替换为你的实际数据 # 第一步:过滤sales>100的有效记录 filtered_data = [item for item in raw_data if item['sales'] > 100] # 第二步:按id分组,同id日期排序 id_date_map = defaultdict(list) for item in filtered_data: # 注意:strptime的格式参数要和你实际的date字段格式匹配,示例为年-月-日格式 date_obj = datetime.strptime(item['date'], '%Y-%m-%d').date() id_date_map[item['id']].append(date_obj) # 每个id的日期升序排序 for id_val in id_date_map: id_date_map[id_val].sort() # 第三步:统计每个id的连续日期组长度 new_frame = [] for id_val, date_list in id_date_map.items(): if not date_list: continue current_count = 1 for i in range(1, len(date_list)): day_diff = (date_list[i] - date_list[i-1]).days if day_diff == 1: current_count += 1 else: # 间隔超过1天,保存上一个连续组 new_frame.append({'id': id_val, 'count': current_count}) current_count = 1 # 保存最后一个连续组 new_frame.append({'id': id_val, 'count': current_count})
效果验证
用示例数据测试:
raw_data = [ {'date':'2024-01-01', 'id':'03', 'sales':120}, {'date':'2024-01-02', 'id':'03', 'sales':150}, {'date':'2024-01-03', 'id':'03', 'sales':110}, {'date':'2024-01-01', 'id':'07', 'sales':130}, {'date':'2024-01-03', 'id':'07', 'sales':140}, ]
运行后得到的new_frame结果为:
[{'id': '03', 'count': 3}, {'id': '07', 'count': 1}, {'id': '07', 'count': 1}]
完全符合要求的输出格式。
内容的提问来源于stack exchange,提问作者paul
相关产品推荐
相关产品推荐

