You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python Pandas处理顺序日志:格式转换、时间差计算及pivot报错解决

解决方案

报错原因

原代码使用pivot报错,是因为同一个user_id + token + action_id分组下存在多条重复记录,pivot要求索引+列的组合必须唯一,所以需要对重复动作做聚合处理,顺序日志场景下通常取每个分组下最早的动作时间即可。

调整后代码实现

预期输出1代码

import pandas as pd

# 带重复动作的测试数据
df = pd.DataFrame({
    'user_id': [7, 12, 45, 7, 12, 12, 7, 12, 7, 12, 91, 12, 12, 91, 91, 91, 91, 45],
    'token': [223, 191, 667, 223, 191, 339, 223, 339, 564, 778, 551, 778, 778, 551, 551, 551, 551, 122],
    'action_id': [1, 1, 2, 3, 2, 1, 2, 2, 1, 1, 1, 4, 5, 5, 3, 5, 2, 1],
    'action_timestamp': [f'timestamp{x}' for x in range(1,19)]
})

# 实际场景请先将时间戳转为datetime类型,方便后续计算时间差
# df['action_timestamp'] = pd.to_datetime(df['action_timestamp'])

# 用pivot_table替代pivot,指定aggfunc自动处理重复记录,这里取min即保留最早的动作时间
output1 = df[df['action_id'].isin([1,2])].pivot_table(
    index=['user_id', 'token'],
    columns='action_id',
    values='action_timestamp',
    aggfunc='min'
).add_prefix('timestamp_action_id_').reset_index().rename_axis(None, axis=1)

# 筛除不同时存在action_id=1和action_id=2的记录
output1 = output1.dropna().reset_index(drop=True)
print(output1)

预期输出2代码

# 计算每个有效token的动作时间差,以下为测试数据的字符串时间转数值差逻辑,实际场景替换为datetime相减即可
# output1['delta'] = output1['timestamp_action_id_2'] - output1['timestamp_action_id_1']
output1['delta'] = output1['timestamp_action_id_2'].str.replace('timestamp','').astype(int) - output1['timestamp_action_id_1'].str.replace('timestamp','').astype(int)

# 按user_id分组计算平均时间差
output2 = output1.groupby('user_id', as_index=False)['delta'].mean().rename(
    columns={'delta':'action_id_1_to_action_id_2_time_delta_average'}
)
print(output2)

逻辑说明

如果业务需求不是取最早的动作,而是取最晚的动作,将aggfunc='min'修改为aggfunc='max'即可;如果需要取action_id=1之后出现的第一个action_id=2,可以先对每个user_id+token分组下的日志按时间升序排序,再去重保留每个action_id的第一条记录,后续处理逻辑和上述代码一致。


内容的提问来源于stack exchange,提问作者Aerodyne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:36:04