如何用Pandas按会话拆分DataFrame(按ID分组,间隔超30秒)
解决方案
要实现按id分组并根据操作间隔(超过30秒)拆分会话,你可以借助Pandas的groupby、diff和cumsum方法完成,步骤如下:
1. 构造示例数据
首先还原你的DataFrame:
import pandas as pd df = pd.DataFrame({ 'id': [1, 2, 3, 1, 1, 3], 'sec': [45, 1, 176, 19, 876, 123] })
2. 核心处理逻辑
# 1. 按id分组,计算组内相邻操作的时间间隔绝对值 df['interval'] = df.groupby('id')['sec'].diff().abs() # 2. 标记会话分割点:间隔超过30秒,或是组内第一条记录(diff返回NaN) df['session_split'] = (df['interval'] > 30) | df['interval'].isna() # 3. 生成每个id下的会话ID:分割点累加得到唯一会话标识 df['session_id'] = df.groupby('id')['session_split'].cumsum() # 4. 按id和会话ID聚合,将sec转为会话列表 session_result = df.groupby(['id', 'session_id'])['sec'].apply(list).reset_index() # 整理成按id展示所有会话的格式 final_result = session_result.groupby('id')['sec'].apply(list).to_dict() print(final_result)
输出结果
{1: [[45, 19], [876]], 2: [[1]], 3: [[176, 123]]}
关键步骤解释
diff().abs():计算每个id组内相邻sec的差值绝对值,得到操作间隔;session_split:标记需要拆分会话的位置,第一条记录默认作为新会话起点;cumsum():对每个id组的分割点进行累加,生成唯一的会话ID,确保同一会话的记录拥有相同ID;- 最后通过两次分组聚合,得到每个id对应的会话列表。
可选:按时间顺序处理会话
如果需要先按sec(时间戳)排序再拆分会话,只需在处理前先排序:
# 先按id和sec排序,保证时间顺序 df_sorted = df.sort_values(['id', 'sec']) # 后续步骤与上述核心逻辑一致 df_sorted['interval'] = df_sorted.groupby('id')['sec'].diff().abs() df_sorted['session_split'] = (df_sorted['interval'] > 30) | df_sorted['interval'].isna() df_sorted['session_id'] = df_sorted.groupby('id')['session_split'].cumsum() session_result_sorted = df_sorted.groupby(['id', 'session_id'])['sec'].apply(list).reset_index() final_result_sorted = session_result_sorted.groupby('id')['sec'].apply(list).to_dict() print(final_result_sorted)
输出:
{1: [[19, 45], [876]], 2: [[1]], 3: [[123, 176]]}
内容的提问来源于stack exchange,提问作者hurricane133
相关产品推荐
相关产品推荐

