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

如何将Pandas分组滚动窗口Lambda计算转为Polars实现

Pandas滚动加权求和逻辑的Polars正确实现

错误原因分析

你之前的代码报错是因为Polars的GroupBy对象没有select方法,同时自定义函数的逻辑和原Pandas代码不符(原Pandas是直接对加权项求和,不是加权平均),需要调整实现方式。

正确Polars实现代码

import polars as pl

lookback_period = 5

# 构造Polars DataFrame(对齐原Pandas数据)
df_data = pl.DataFrame({
    'date': [
        '31/12/2021', '07/01/2022', '14/01/2022', '21/01/2022', '28/01/2022',
        '04/02/2022', '11/02/2022', '18/02/2022', '25/02/2022', '04/03/2022',
        '11/03/2022', '18/03/2022', '25/03/2022', '01/04/2022', '08/04/2022',
        '14/04/2022', '22/04/2022', '29/04/2022', '06/05/2022', '13/05/2022',
        '20/05/2022'
    ],
    'close-LDPM': [
        10.87, 11.04, 11.36, 11.01, 12.07, 12.44, 12.38, 10.06, 10.12, 8.1,
        8.45, 9.05, 9.27, 9.51, 9.66, 8.49, 8.53, 7.96, 7.71, 7.65, 7.77
    ],
    'ticker': ['ERIC'] * 21,
    'timeframe': ['1 W'] * 21
})

# 定义对齐原Pandas逻辑的自定义滚动函数
def custom_weighted_sum(s: pl.Series) -> float:
    # 仅当窗口长度达到lookback_period时计算,否则返回None(对应NaN)
    if len(s) != lookback_period:
        return None
    # 反转序列,使最新元素对应权重1/1,倒数第二个对应1/2,以此类推
    reversed_series = s.reverse()
    # 生成权重:1/1, 1/2, ..., 1/5
    weights = pl.Series([1/i for i in range(1, lookback_period + 1)])
    # 计算加权和
    return (reversed_series * weights).sum()

# 分组(ticker+timeframe)后应用滚动窗口计算
df_data = df_data.with_columns(
    LDPS_w = pl.col('close-LDPM')
    .rolling(window_size=lookback_period, min_periods=lookback_period)
    .apply(custom_weighted_sum)
    .over(['ticker', 'timeframe'])
)

print(df_data)

关键说明

  1. Polars分组滚动的正确姿势:使用over子句直接在列表达式上实现分组内的滚动计算,无需先调用group_by,代码更简洁。
  2. 对齐原逻辑:函数中先反转序列,确保最新的元素对应最大的权重(1/1),和原Pandas代码中x[-i]/i的逻辑完全匹配。
  3. 控制窗口生效条件:通过min_periods=lookback_period和函数内的长度判断,确保只有窗口元素数量达到5时才输出计算结果,否则返回None(对应Pandas的NaN)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 22:20:13