使用Pandas计算各时间点不同事件的订单数量
统计各时间点订单事件状态数量
问题场景
现有如下结构的DataFrame,记录了订单在不同时间的事件变化:
time ID event ----- -- ----- 10:00 A start 10:01 B start 10:02 A process 10:03 A finish 10:04 B process 10:05 B finish
需求是新增列num_start、num_process、num_finish,统计每行对应时间点下,处于各事件状态的订单数量(订单无新事件记录时保持当前状态),预期输出如下:
time ID event num_start num_process num_finish ----- -- ----- --------- ----------- ---------- 10:00 A start 1 0 0 10:01 B start 2 0 0 10:02 A process 1 1 0 10:03 A finish 1 0 1 10:04 B process 0 1 1 10:05 B finish 0 0 2
解决方案(Pandas实现)
import pandas as pd # 构造输入数据(实际使用时替换为你的DataFrame) df = pd.DataFrame({ 'time': ['10:00', '10:01', '10:02', '10:03', '10:04', '10:05'], 'ID': ['A', 'B', 'A', 'A', 'B', 'B'], 'event': ['start', 'start', 'process', 'finish', 'process', 'finish'] }) # 提取所有唯一时间点和订单ID unique_times = df['time'].unique() unique_ids = df['ID'].unique() # 生成每个订单在所有时间点的状态记录 status_df = pd.DataFrame() for order_id in unique_ids: # 获取当前订单的事件并按时间排序 order_events = df[df['ID'] == order_id].sort_values('time').set_index('time')['event'] # 填充所有时间点的状态(无新事件时沿用前序状态) order_status = order_events.reindex(unique_times).ffill() # 转换为DataFrame并添加订单ID列 order_status_df = order_status.reset_index(name='current_event') order_status_df['ID'] = order_id status_df = pd.concat([status_df, order_status_df], ignore_index=True) # 按时间统计各状态的订单数量 status_counts = status_df.groupby('time')['current_event'].value_counts().unstack(fill_value=0) status_counts = status_counts.add_prefix('num_').reset_index() # 合并统计结果到原DataFrame result = pd.merge(df, status_counts, on='time', how='left') # 调整列顺序匹配预期输出 result = result[['time', 'ID', 'event', 'num_start', 'num_process', 'num_finish']] print(result)
逻辑说明
- 状态填充:对每个订单,提取其所有事件记录并按时间排序,通过
reindex覆盖所有时间点,再用ffill()(前向填充)补全无事件时间点的状态,确保每个订单在所有时间点都有状态记录。 - 统计计数:按时间分组,对每个时间点的所有订单状态进行计数,得到各状态的订单数量。
- 合并结果:将统计得到的各状态数量与原DataFrame按时间合并,得到每行对应的状态计数。
内容的提问来源于stack exchange,提问作者Jan T.
相关产品推荐
相关产品推荐

