如何在学生线上课程点击行为时序数据中插入分隔行标记休息时段
线上课程学生点击行为序列休息标识实现
项目背景
我正在开展一项线上课程学生点击行为分析项目,需要将点击路径作为序列数据处理,原始数据样例如下:
user_id timestamp duration_sec Page 545301 8/25/2020 14:49 5 home 545301 8/25/2020 15:00 10 instructor 545301 9/2/2020 13:33 5 home 545301 9/8/2020 12:46 3 home 545301 9/9/2020 11:10 3 home 545301 9/9/2020 13:24 8 general 545301 9/9/2020 14:33 12 zoom
需求说明
需要在行为子序列之间插入分隔行,标识学生两次行为序列间的休息时段(即两次点击间隔超过3小时的场景),处理后预期数据样例如下:
user_id timestamp duration_sec Page 545301 8/25/2020 14:49 5 home 545301 8/25/2020 15:00 10 instructor 545301 8/25/2020 15:10 99999 break 545301 9/2/2020 13:33 5 home 545301 9/2/2020 13:38 99999 break 545301 9/8/2020 12:46 3 home 545301 9/8/2020 12:49 99999 break 545301 9/9/2020 11:10 3 home 545301 9/9/2020 13:24 8 general 545301 9/9/2020 14:33 12 zoom
核心实现思路
整体逻辑可以拆解为3步:
- 数据预处理:首先将时间戳字段转换为pandas datetime格式,避免字符串计算时间差出现异常
- 间隔计算:按用户id分组后,通过
shift函数将下一次点击的开始时间上移生成对比列,计算相邻两次点击的时间间隔,单位转为小时 - 插入分隔行:遍历所有间隔超过3小时的位置,生成对应休息行数据插入到两次点击中间,最后重置全局索引即可
已验证实现代码
更新
我已在@Abdel的帮助下完成功能实现:
第一步,新增gap列,计算与下一次点击的时间间隔(单位:小时),代码如下:
df['gap']= (df['start_time_shift'] - df['start_time']).dt.total_seconds()/3600
第二步,定义插入休息分隔行的函数,代码如下:
def add_breaks(df): List_of_breaks=[] for i in range(len(df.index)): if df.gap.iloc[i] > 3: List_of_breaks.append(i) for i in List_of_breaks: line = pd.DataFrame({'course_id':df.course_id.iloc[i], "user_id": df.user_id.iloc[i], "start_time": df.end_time.iloc[i], 'end_time':df.start_time_shift.iloc[i], 'start_time_shift':df.start_time_shift.iloc[i+1], 'duration_min':df.start_time_shift.iloc[i]-df.end_time.iloc[i], 'gap': 'gap', 'page':'break'}, index=[i+1]) df=pd.concat([df.iloc[:i+1], line, df.iloc[i+2:]]).reset_index(drop=True) return(df)
我对@Abdel的方案做了两处调整:
- 将过滤条件改为gap的数值
- 优化行插入拼接逻辑,调整为
df.iloc[:i+1], line, df.iloc[i+2:]]).reset_index(drop=True)
内容的提问来源于stack exchange,提问作者qiwei men
相关产品推荐
相关产品推荐

