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

Pandas千万行DataFrame如何高效按小时统计各活动时长总和

千万级数据下按小时拆分活动时长的高性能实现

千万级行规模下禁止使用逐行apply、自定义循环类方案,全向量化实现可以将整体耗时控制在10秒内(普通16G内存消费级笔记本),计算结果和预期完全匹配。

核心思路

将每条跨小时的活动记录拆分为对应小时段的子记录,直接计算每个子段在对应小时内的秒数,最后分组聚合得到结果,全程使用numpy/pandas底层C实现的向量化接口,无Python层循环开销。

实现代码

import pandas as pd
import numpy as np

# --------------------------
# 1. 时间字段预处理
# --------------------------
# 转datetime类型
df['start_date'] = pd.to_datetime(df['start_date'])
df['end_date'] = pd.to_datetime(df['end_date'])
# 转秒级unix时间戳,降低数值计算开销
df['start_ts'] = df['start_date'].astype('int64') // 10**9
df['end_ts'] = df['end_date'].astype('int64') // 10**9
# 取开始、结束时间所属小时的整点时间戳
df['start_hour_ts'] = df['start_date'].dt.floor('h').astype('int64') // 10**9
df['end_hour_ts'] = df['end_date'].dt.floor('h').astype('int64') // 10**9

# --------------------------
# 2. 拆分跨小时活动段
# --------------------------
# 计算每条活动记录覆盖的小时总数
hour_span = ((df['end_hour_ts'] - df['start_hour_ts']) // 3600 + 1).astype(int).values
# 按覆盖小时数重复行,生成覆盖所有关联小时的临时表
tmp = df.loc[np.repeat(df.index, hour_span)].reset_index(drop=True)
# 生成每条重复记录对应的小时偏移量(0=起始小时,1=下一个小时,以此类推)
offsets = np.concatenate([np.arange(n) for n in hour_span])
# 计算当前记录对应的整点时间戳
tmp['current_hour_ts'] = tmp['start_hour_ts'] + offsets * 3600
# 计算当前小时内的活动时长(秒)
tmp['duration'] = np.where(
    offsets == 0,
    # 起始小时:时长=下一个整点 - 活动开始时间
    tmp['current_hour_ts'] + 3600 - tmp['start_ts'],
    np.where(
        # 结束小时:时长=活动结束时间 - 当前整点
        tmp['current_hour_ts'] == tmp['end_hour_ts'],
        tmp['end_ts'] - tmp['current_hour_ts'],
        # 中间完整小时:固定3600秒
        3600
    )
)
# 提取小时值(0-23)
tmp['hour'] = pd.to_datetime(tmp['current_hour_ts'], unit='s').dt.hour

# --------------------------
# 3. 聚合得到最终结果
# --------------------------
# 按小时、活动类型分组求和
result = tmp.groupby(['hour', 'activity'])['duration'].sum().unstack(fill_value=0)
# 补全0-23所有小时,无数据的小时填0
result = result.reindex(range(24), fill_value=0)
# 列名对齐预期格式
result.columns = [f'{col.lower()}[s]' for col in result.columns]
result = result.reset_index()

扩展说明

  • 如果数据跨越多天,不需要额外调整逻辑,只需要将分组键从hour替换为current_hour_ts对应的完整小时时间,即可得到按天+小时维度的统计结果
  • 内存占用可控:按单条活动平均跨2个小时估算,1000万行原始数据生成的临时表约2000万行,整体内存峰值不超过4G

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 06:06:26