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

如何为带用户ID的时间序列数据计算可扩展的移动周平均值?

问题

我有带用户ID列(uid)和连续数值列(col)的时间序列数据,想为每个用户计算数值的移动周平均值并生成新列。以下是生成样本数据集的代码:

import pandas as pd
import numpy as np
df = pd.DataFrame(index=pd.date_range(freq=f'{60}T',start='2020-01-01',periods=(1)*24*14))
df['col'] = np.random.random_integers(0, 250, size= df.shape[0])
df['uid'] = 1
df2 = pd.DataFrame(index=pd.date_range(freq=f'{60}T',start='2020-01-01',periods=(1)*24*14))
df2['col'] = np.random.random_integers(0, 150, size= df2.shape[0])
df2['uid'] = 2
df3=pd.concat([df, df2]).reset_index()
df3

样本中每个用户有2周数据,要求每个用户生成两个平均值:

  1. 第一周所有行填充第一周的均值
  2. 第二周所有行填充前两周均值的平均值(即(第一周均值+第二周均值)/2)
    真实数据集规模较大,需要可扩展的实现方案。

期望输出示例:

index      uid   col    week_average
2020-01-01 00:00:00    1   104    week1_uid1_mean
2020-01-01 01:00:00    1   150    week1_uid1_mean
2020-01-01 02:00:00    1   243    week1_uid1_mean 
....
2020-01-08 00:00:00    1   174    (week1_uid1_mean+week2_uid1_mean)/2
2020-01-08 01:00:00    1   24     (week1_uid1_mean+week2_uid1_mean)/2
... 

解决方案

步骤1:处理时间列并标记用户内周数

先确保时间列格式正确,再按用户分组,以每个用户的最早数据时间为基准,标记每行属于该用户的第几周:

# 确保时间列是datetime类型
df3['index'] = pd.to_datetime(df3['index'])

# 按uid分组,计算每行对应的周序号(从1开始)
df3['week_num'] = df3.groupby('uid')['index'].transform(
    lambda x: (x - x.min()).dt.days // 7 + 1
)

步骤2:计算用户每周的均值

按用户和周数分组,计算每周的col均值,再将结果合并回原数据集:

# 计算每个用户每周的col均值
weekly_means = df3.groupby(['uid', 'week_num'])['col'].mean().reset_index(name='weekly_mean')

# 合并回原数据,让每行匹配所在周的均值
df3 = df3.merge(weekly_means, on=['uid', 'week_num'], how='left')

步骤3:计算移动周平均(累计均值)

按用户分组,对每周均值计算累计平均值,即前N周均值的平均,再将该值填充到对应周的所有行:

# 按uid分组,计算累计移动周平均
df3['week_average'] = df3.groupby('uid')['weekly_mean'].transform(
    lambda x: x.expanding().mean()
)

完整可运行代码

整合所有步骤,同时替换已弃用的random_integers为randint:

import pandas as pd
import numpy as np

# 生成样本数据
df = pd.DataFrame(index=pd.date_range(freq=f'{60}T',start='2020-01-01',periods=(1)*24*14))
df['col'] = np.random.randint(0, 250, size= df.shape[0])
df['uid'] = 1
df2 = pd.DataFrame(index=pd.date_range(freq=f'{60}T',start='2020-01-01',periods=(1)*24*14))
df2['col'] = np.random.randint(0, 150, size= df2.shape[0])
df2['uid'] = 2
df3=pd.concat([df, df2]).reset_index()

# 步骤1:处理时间并标记周数
df3['index'] = pd.to_datetime(df3['index'])
df3['week_num'] = df3.groupby('uid')['index'].transform(
    lambda x: (x - x.min()).dt.days // 7 + 1
)

# 步骤2:计算每周均值
weekly_means = df3.groupby(['uid', 'week_num'])['col'].mean().reset_index(name='weekly_mean')
df3 = df3.merge(weekly_means, on=['uid', 'week_num'], how='left')

# 步骤3:计算移动周平均
df3['week_average'] = df3.groupby('uid')['weekly_mean'].transform(
    lambda x: x.expanding().mean()
)

# 查看结果(可选)
print(df3[['index', 'uid', 'col', 'week_average']].head())

方案说明

  • 全程使用Pandas内置的分组和向量化运算,避免循环,性能高效,可轻松扩展到百万级以上数据
  • expanding().mean()直接实现“前N周均值的平均”需求,逻辑简洁清晰
  • 所有操作都基于用户分组,确保每个用户的周计算独立不干扰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 20:15:50