如何按起止时间戳对pandas DataFrame中多会话账号的行分组
解决方案
实现思路
由于应用限制同一账号同一时间仅可存在一个活跃会话,可按以下逻辑实现多会话自动匹配:
- 先将时间戳转换为datetime类型并全局按时间排序,保证所有事件的时序正确
- 过滤掉会话内的操作事件,仅保留
start、end两类会话边界事件 - 按账号分组后,每遇到一个
start事件则将会话ID加1,同一会话的start和对应的end会被标记为相同的会话ID - 通过行列转换将同一会话的起止时间合并为一行,未匹配到
end的活跃会话结束时间自动填充为NaN
示例代码
import pandas as pd # 示例数据初始化 data1 = {'timestamp': ['01-01-2021 12:00:00','01-01-2021 12:01:00','01-01-2021 12:02:00','01-01-2021 12:03:00','01-01-2021 12:04:00','01-01-2021 12:05:00','01-01-2021 12:06:00','01-01-2021 12:07:00','01-01-2021 12:08:00','01-01-2021 12:09:00','01-01-2021 12:10:00','01-01-2021 12:11:00','01-01-2021 12:12:00','01-01-2021 12:13:00','01-01-2021 12:14:00'], 'event': ['start','x','y','start','z','end','x','end','start','x','end','start','q','end','start'], 'account': ['bob','bob','bob','jane','bob','bob','jane','jane','todd','todd','todd','bob','bob','bob','ned'] } df1 = pd.DataFrame(data1) # 1. 时间格式转换+全局按时间排序 df1['timestamp'] = pd.to_datetime(df1['timestamp'], format='%d-%m-%Y %H:%M:%S') df1 = df1.sort_values('timestamp').reset_index(drop=True) # 2. 筛选会话边界事件 session_events = df1[df1['event'].isin(['start', 'end'])].copy() # 3. 按账号生成会话ID session_events['session_id'] = session_events.groupby('account')['event'].transform(lambda x: (x == 'start').cumsum()) # 4. 行列转换生成会话报告 session_report = session_events.pivot_table( index=['account', 'session_id'], columns='event', values='timestamp', aggfunc='first' ).reset_index()[['account', 'start', 'end']] # (可选)将时间转回字符串格式,符合示例输出要求 session_report['start'] = session_report['start'].dt.strftime('%d-%m-%Y %H:%M:%S') session_report['end'] = session_report['end'].dt.strftime('%d-%m-%Y %H:%M:%S').where(session_report['end'].notna(), pd.NA) # (可选)按会话开始时间排序,匹配预期输出顺序 session_report = session_report.sort_values('start').reset_index(drop=True) print(session_report)
输出结果
account start end 0 bob 01-01-2021 12:00:00 01-01-2021 12:05:00 1 jane 01-01-2021 12:03:00 01-01-2021 12:07:00 2 todd 01-01-2021 12:08:00 01-01-2021 12:10:00 3 bob 01-01-2021 12:11:00 01-01-2021 12:13:00 4 ned 01-01-2021 12:14:00 <NA>
内容的提问来源于stack exchange,提问作者user3246693
相关产品推荐
相关产品推荐

