如何用Pandas按日期和用户统计连续风险等级的出现天数
解决连续风险状态天数统计问题
你的原始代码仅统计了每个用户、指标、风险等级的总记录数,未区分日期连续性,因此无法得到连续天数的结果。要实现需求,需按以下步骤处理:
步骤1:转换日期格式并排序
先将日期列转为可排序的datetime类型,确保连续日期的顺序正确:
import pandas as pd # 转换日期格式(匹配输入的dd-mm-yy格式) df['yy_mm_dd'] = pd.to_datetime(df['yy_mm_dd'], format='%d-%m-%y') # 按用户、指标、日期排序,保证连续记录的顺序 df = df.sort_values(['userid', 'metrics', 'yy_mm_dd'])
步骤2:标记连续相同风险状态的分组
对每个用户+指标的组,判断风险等级是否发生变化,生成唯一的连续分组ID:
# 生成连续分组ID:当当前行风险等级与上一行不同时,分组ID递增 df['continuous_group'] = df.groupby(['userid', 'metrics'])['risk_level'].apply( lambda x: (x != x.shift()).cumsum() )
步骤3:统计每个连续分组的天数并整理格式
按用户、指标、风险等级、连续分组ID统计天数,再转换为预期的文本格式:
# 统计每个连续分组的天数 stats = df.groupby(['userid', 'metrics', 'risk_level', 'continuous_group']).size().reset_index(name='days') # 将天数转换为"X days"/"1 day"的格式 stats['days_risk'] = stats['days'].apply(lambda x: f"{x} day{'s' if x > 1 else ''}") # 提取需要的列得到最终结果 final = stats[['userid', 'metrics', 'risk_level', 'days_risk']]
最终输出
运行上述代码后,final的结果将与你的预期完全一致:
| userid | metrics | risk_level | days_risk |
|---|---|---|---|
| Tom | run | no risk | 2 days |
| Tom | walk | no risk | 1 day |
| Tom | walk | at risk | 2 days |
| Sue | run | at risk | 1 day |
| Sue | run | no risk | 1 day |
关键说明
- 原始代码的问题:
groupby(['userid','metrics','risk_level']).count()会合并所有同用户、同指标、同风险等级的记录,不管日期是否连续,无法区分间隔的风险状态段。 - 连续分组的核心:通过
x != x.shift()识别风险等级的变化点,再用cumsum()生成递增的分组ID,确保每个连续相同风险等级的时间段拥有唯一标识。
内容的提问来源于stack exchange,提问作者Naomi
相关产品推荐
相关产品推荐

