如何为Pandas DataFrame按账户实现带可变min_periods的滚动平均?
按账户动态设置min_periods计算滚动平均的解决方案
问题场景
现有包含多账户历史数据的DataFrame,需按accountID分组对diffs列计算窗口固定为10的滚动平均值,但每个账户的min_periods(计算滚动平均所需的最小前置数据量)由自身的minuploads列指定:当当前行的前置有效数据量未达到该账户的minuploads要求时,不计算滚动平均,改用模型值填充。
示例DataFrame:
| accountID | date | diffs | minuploads |
|---|---|---|---|
| 1001 | 2020-01-12 | 7 | 8 |
| 1001 | 2020-01-19 | 7 | 8 |
| 1001 | 2020-01-20 | 1 | 8 |
| 1001 | 2020-01-26 | 6 | 8 |
| 1002 | 2020-01-10 | 2 | 10 |
| 1002 | 2020-01-13 | 3 | 10 |
| 1002 | 2020-01-16 | 3 | 10 |
| 1002 | 2020-01-18 | 2 | 10 |
报错原因分析
你之前的代码报错核心问题:
- 单分组列的
transform中,lambda参数是单列Series(仅diffs),不存在minuploads字段,直接访问会触发KeyError。 - 多分组列的
transform中,rolling的min_periods要求是标量值,无法直接传入Series类型的x['minuploads']。
解决方案
前提:确保数据按账户+时间排序
滚动平均依赖时间顺序,先执行排序:
df = df.sort_values(['accountID', 'date'])
方案1:每个账户minuploads值统一的场景
假设每个账户的minuploads值是固定的(如示例所示),用groupby.apply处理每个分组:
import pandas as pd def process_account_group(group): # 获取当前账户的min_periods固定值 min_periods = group['minuploads'].iloc[0] # 计算滚动平均 group['ma'] = group['diffs'].rolling(window=10, min_periods=min_periods).mean() # 填充未满足条件的行(NaN替换为模型值,这里假设模型值列名为model_pred) group['ma'] = group['ma'].fillna(group['model_pred']) # 若模型值是固定值,可替换为:group['ma'] = group['ma'].fillna(你的模型值) return group # 应用到所有分组 df = df.groupby('accountID').apply(process_account_group)
方案2:每行minuploads值可变的场景
如果存在同一账户内minuploads每行不同的情况,需逐行判断前置数据量:
import pandas as pd import numpy as np def process_dynamic_min_periods(group): # 计算当前行在账户内的累计行数(即前置数据量+1) group['row_index'] = group.cumcount() + 1 # 先计算所有可能的滚动平均(min_periods设为1) group['ma_temp'] = group['diffs'].rolling(window=10, min_periods=1).mean() # 条件判断:行数不足minuploads则用模型值,否则用滚动平均 group['ma'] = np.where( group['row_index'] < group['minuploads'], group['model_pred'], # 替换为你的模型值列或固定值 group['ma_temp'] ) # 清理临时列 return group.drop(columns=['row_index', 'ma_temp']) df = df.groupby('accountID').apply(process_dynamic_min_periods)
验证示例结果
以示例数据为例:
- accountID=1001的minuploads=8,当前仅4行数据,所有行的
ma都会被模型值填充 - accountID=1002的minuploads=10,当前仅4行数据,同样所有行
ma用模型值填充
内容的提问来源于stack exchange,提问作者Nolan G
相关产品推荐
相关产品推荐

