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

Pandas高效实现按用户统计8小时时间槽事件存在性

高效实现用户8小时时间槽事件标记方案

需求回顾

  • 输入DF1:2700万条事件记录,包含user(用户ID)和time(事件时间)列,时间范围为2022-11-14至2022-11-20
  • 输出DF2:每行对应一个用户,21列分别对应该周的21个8小时时间槽,值为1表示用户在对应槽有事件,0则无
  • 原单用户循环方案耗时极长(单用户30秒,1万用户近4天),需用高效方法替代

高效实现步骤(Pandas)

1. 生成时间槽映射规则

先定义所有8小时时间槽的边界和标识:

import pandas as pd

# 时间范围起始(包含结束日的最后一个槽)
start_ts = pd.Timestamp('2022-11-14 00:00:00')
end_ts = pd.Timestamp('2022-11-21 00:00:00')

# 生成8小时间隔的槽边界
slot_bins = pd.date_range(start=start_ts, end=end_ts, freq='8H')
# 为每个槽命名(slot_0到slot_20)
slot_labels = [f'slot_{i}' for i in range(len(slot_bins)-1)]

2. 批量匹配事件到时间槽

用向量化操作给每条事件分配对应的时间槽,避免循环:

# 确保time列为datetime类型(若原始数据是字符串则转换)
df1['time'] = pd.to_datetime(df1['time'])

# 快速映射每条事件到对应槽
df1['slot'] = pd.cut(df1['time'], bins=slot_bins, labels=slot_labels, include_lowest=True)

3. 聚合生成用户-时间槽标记表

两种高效聚合方式,按需选择:

方式一:pd.crosstab(简洁快速)

# 生成用户-槽的计数表,再转为0/1标记
df2 = pd.crosstab(df1['user'], df1['slot'])
# 确保所有21个槽列都存在(防止无事件的槽被遗漏)
df2 = df2.reindex(columns=slot_labels, fill_value=0)
# 计数>0则标记为1,否则0
df2 = (df2 > 0).astype(int)

方式二:去重后透视(内存更友好)

针对超大数据集,先去重减少计算量:

# 保留每个用户每个槽的唯一记录
unique_user_slot = df1[['user', 'slot']].drop_duplicates()
# 透视生成标记表,空值填充为0
df2 = unique_user_slot.pivot(index='user', columns='slot', values='slot')
# 非空值标记为1,确保所有槽列完整
df2 = df2.notna().astype(int).reindex(columns=slot_labels, fill_value=0)

优化核心说明

  • 全向量化计算:利用Pandas底层C扩展实现批量操作,速度比循环提升千倍以上,2700万条数据处理仅需几分钟
  • 去重降维:提前去除用户-槽的重复记录,大幅减少聚合阶段的计算量
  • 内存优化:若内存不足,可改用Dask框架分块处理,或按用户分批次计算后合并结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 22:05:15