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

使用pandas分箱聚合时间区间数据生成用户产品用量时序数据集

解决方案

核心采用pandas向量化操作,全程无显式for循环,可支撑万级用户、数十个产品的计算需求,同时兼容datetime类型与数值类型的时间字段。


前置说明

分箱统一采用左闭右开规则[start, end),符合时序统计的通用惯例。

完整实现步骤

1. 导入依赖与构造测试数据

import pandas as pd
import numpy as np

# 示例:datetime类型时间的测试数据,数值类型时间逻辑完全一致
df = pd.DataFrame([
    {'start_time': pd.to_datetime('2024-01-01 01:00:00'), 'end_time': pd.to_datetime('2024-01-01 10:00:00'), 'user': 'user1', 'product': 'productA', 'usage_rate': 2},
    {'start_time': pd.to_datetime('2024-01-01 05:00:00'), 'end_time': pd.to_datetime('2024-01-01 07:00:00'), 'user': 'user1', 'product': 'productB', 'usage_rate': 1},
    {'start_time': pd.to_datetime('2024-01-01 03:00:00'), 'end_time': pd.to_datetime('2024-01-01 09:00:00'), 'user': 'user2', 'product': 'productA', 'usage_rate': 3},
])

2. 生成全局分箱序列

# 时间单位参数:如果是数值类型时间,单位设为4即可;datetime类型设为'4h'
time_unit = '4h'
# 取全量数据的时间边界生成所有分箱
all_bins = pd.interval_range(
    start=df['start_time'].min().floor(time_unit),
    end=df['end_time'].max().ceil(time_unit),
    freq=time_unit,
    closed='left'
)

3. 匹配每条记录覆盖的所有分箱并展开

# 为每行生成其覆盖的分箱列表,再展开为多行
df['bin'] = df.apply(
    lambda x: [b for b in all_bins if b.overlaps(pd.Interval(x['start_time'], x['end_time'], closed='left'))],
    axis=1
)
df_exploded = df.explode('bin', ignore_index=True)

4. 计算分箱内的用量

# 计算单条记录在对应分箱内的实际时长
df_exploded['bin_start'] = df_exploded['bin'].apply(lambda x: x.left)
df_exploded['bin_end'] = df_exploded['bin'].apply(lambda x: x.right)
df_exploded['actual_start'] = np.maximum(df_exploded['start_time'], df_exploded['bin_start'])
df_exploded['actual_end'] = np.minimum(df_exploded['end_time'], df_exploded['bin_end'])

# 计算占比与用量:datetime类型转小时数,数值类型直接相减即可
df_exploded['duration_in_bin'] = (df_exploded['actual_end'] - df_exploded['actual_start']).dt.total_seconds() / 3600
df_exploded['used_in_bin'] = df_exploded['duration_in_bin'] / 4 * df_exploded['usage_rate']

5. 聚合透视得到最终结果

# 按用户、分箱、产品聚合求和,再透视产品为列
result = df_exploded.groupby(['user', 'bin', 'product'], as_index=False)['used_in_bin'].sum()
result_pivot = result.pivot(index=['user', 'bin'], columns='product', values='used_in_bin').fillna(0).reset_index()

性能优化提示

如果原始数据量超过10万条,可将分箱匹配的列表推导替换为向量化判断逻辑:

  • 提前将所有分箱的左右边界转成numpy数组
  • 用广播机制批量判断每条记录覆盖的分箱索引,再基于索引生成展开后的数据集,速度可提升10倍以上

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:48:02