基于Pandas计算Hit=1的事件周期时长及统计指标并构建结果DF
Pandas 实现Hit事件周期统计方案
1. 数据预处理
首先需要将时间列转为 datetime 格式,按ID和时间排序并去重,避免重复记录干扰周期划分:
import pandas as pd # 构造示例数据(替换为你的实际数据) data = { 'ID': [989]*9, 'Time': ['2021-04-22 06:07:12', '2021-04-24 09:35:12', '2021-04-24 19:35:12', '2021-04-25 09:35:12', '2021-04-25 12:35:12', '2021-04-25 23:35:12', '2021-04-24 09:35:12', '2021-04-24 09:35:12', '2021-04-24 09:35:12'], 'Entry': [2,4,6,8,3,1,4,7,5], 'Hit': [0,1,1,1,0,0,1,1,1] } df = pd.DataFrame(data) # 核心预处理步骤 df['Time'] = pd.to_datetime(df['Time']) df = df.sort_values(['ID', 'Time']).drop_duplicates(subset=['ID', 'Time', 'Hit'], keep='first')
2. 划分Hit=1的连续事件周期
通过标记Hit状态的切换,为每个连续的Hit=1时间段分配唯一周期ID:
def assign_episode_ids(group): # 标记周期起始点:从Hit=0切换到Hit=1的位置 group['episode_start'] = (group['Hit'] == 1) & (group['Hit'].shift(1) != 1) # 累加生成周期ID,仅对Hit=1的行生效 group['episode_id'] = group['episode_start'].cumsum() group['episode_id'] = group['episode_id'].where(group['Hit'] == 1, pd.NA) return group df = df.groupby('ID').apply(assign_episode_ids).reset_index(drop=True)
3. 计算周期时长与统计指标
计算每个周期的时长,再聚合得到每个ID的周期数量、最长时长、均值、中位数,并将各周期时长转为宽格式列:
# 计算每个周期的起止时间及时长(转小时更直观) episode_durations = df.groupby(['ID', 'episode_id']).agg( start_time=('Time', 'min'), end_time=('Time', 'max') ).assign( duration=lambda x: x['end_time'] - x['start_time'], duration_hours=lambda x: (x['end_time'] - x['start_time']).dt.total_seconds() / 3600 ).reset_index() # 转换为宽格式:每个周期时长单独成列(duration_ep_1、duration_ep_2...) duration_wide = episode_durations.pivot( index='ID', columns='episode_id', values='duration_hours' ).rename(columns=lambda x: f'duration_ep_{x}') # 聚合统计指标 stats = episode_durations.groupby('ID').agg( No_Epsiode=('episode_id', 'nunique'), maxlen=('duration_hours', 'max'), Median_ep=('duration_hours', 'median'), Mean_ep=('duration_hours', 'mean') ) # 合并结果并调整列顺序 result_df = pd.merge(stats, duration_wide, on='ID').reset_index() result_df = result_df[['ID', 'No_Epsiode', 'maxlen'] + [col for col in duration_wide.columns] + ['Median_ep', 'Mean_ep']]
最终结果示例
运行后result_df将呈现你需要的结构,针对示例数据的输出如下:
| ID | No_Epsiode | maxlen | duration_ep_1 | Median_ep | Mean_ep |
|---|---|---|---|---|---|
| 989 | 1 | 24 | 24 | 24 | 24 |
内容的提问来源于stack exchange,提问作者lopusfx
相关产品推荐
相关产品推荐

