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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:36:03