如何在Pandas中实现按观测时间远近加权的时间加权移动平均
Pandas 不等间隔时间加权移动平均实现方案
需求说明
要实现权重和观测值新近程度成正比的时间加权移动平均,适配不同游泳选手观测时间间隔不一致的场景,解决原生ewm方法仅按位置加权、无法识别实际时间间隔的问题。
前置依赖与示例数据
import pandas as pd import numpy as np # 示例数据构建 dates = ['01/01/2021','02/01/2021','03/01/2021','04/01/2021','05/01/2021','06/01/2021'] swimmer1_place = ['1','1','4','3',np.nan,np.nan,] swimmer2_place = [np.nan,'3','1',np.nan,'4','2'] swimmer3_place = ['2','2','3',np.nan,'3','1'] df = pd.DataFrame({'date':dates,'swimmer_1_place':swimmer1_place,'swimmer_2_place':swimmer2_place,'swimmer_3_place':swimmer3_place}) df['date'] = pd.to_datetime(df['date'])
实现步骤
1. 数据预处理
先把宽格式的选手数据转换为长格式,方便按选手分组处理,同时将排名列转换为数值类型:
df_melt = df.melt(id_vars='date', var_name='swimmer', value_name='place') df_melt['place'] = pd.to_numeric(df_melt['place'], errors='coerce') df_melt = df_melt.sort_values(['swimmer', 'date']).reset_index(drop=True)
2. 自定义时间加权平均计算函数
这里采用指数衰减权重计算逻辑,可通过半衰期参数调整权重衰减速度,也可根据业务需求替换为线性权重逻辑:
def calculate_twma(group, half_life_days=7): """ 按分组计算时间加权移动平均 :param group: 单个选手的所有观测数据分组 :param half_life_days: 权重半衰期,观测间隔达到该天数时,权重衰减为原值的1/2 :return: 新增twma列的分组数据 """ twma_list = [] for _, current_row in group.iterrows(): current_dt = current_row['date'] # 取当前时点前的所有有效历史观测 valid_history = group[group['date'] <= current_dt].dropna(subset=['place']) if valid_history.empty: twma_list.append(np.nan) continue # 计算历史观测与当前时点的天数差 day_gap = (current_dt - valid_history['date']).dt.days # 指数衰减权重:间隔越短权重越高 weights = np.exp(-day_gap / half_life_days) # 计算加权平均 twma_val = (valid_history['place'] * weights).sum() / weights.sum() twma_list.append(twma_val) group['twma'] = twma_list return group
如果需要使用线性权重,将权重计算行替换为:
weights = 1 / (day_gap + 1)
3. 分组计算并转换结果格式
# 按选手分组计算TWMA df_result = df_melt.groupby('swimmer', group_keys=False).apply(calculate_twma) # 转换回宽表方便查看 df_wide = df_result.pivot(index='date', columns='swimmer', values=['place', 'twma']).reset_index()
提示:如果数据集规模较大(十万行以上),可将逐行循环逻辑替换为
rolling的时间窗口调用,配合自定义加权函数进一步提升运行效率,核心权重计算逻辑无需修改。
方案优势
- 完全基于实际日期差计算权重,不受观测值缺失、观测间隔不一致的影响,适配不同选手的异质性观测规律
- 权重计算逻辑可灵活调整,支持指数衰减、线性衰减等多种加权规则
- 自动跳过空值观测,不会因为空值打断加权计算逻辑
内容的提问来源于stack exchange,提问作者AI92
相关产品推荐
相关产品推荐

