如何在Polars中计算扩展窗口特征(均值、标准差等)?
在Polars中计算扩展窗口特征的方法
Polars完全支持扩展窗口(从起始行到当前行的滚动窗口)的统计量计算,无需切换到Pandas,下面是具体实现方式:
一、内置累计函数(快速处理常见统计量)
对于均值、标准差这类常见需求,Polars提供了直接的cum_*系列函数,一步到位计算扩展窗口结果:
示例代码
import polars as pl # 构造测试数据 df = pl.DataFrame({ "date": pl.date_range(start="2023-01-01", end="2023-01-05", interval="1d"), "value": [10, 20, 30, 40, 50] }) # 计算扩展窗口均值、标准差 df = df.with_columns( pl.col("value").cum_mean().alias("expanding_mean"), # ddof参数设置自由度,和Pandas逻辑一致 pl.col("value").cum_std(ddof=0).alias("expanding_std") ) print(df)
输出结果
shape: (5, 4) ┌────────────┬───────┬────────────────┬────────────────┐ │ date ┆ value ┆ expanding_mean ┆ expanding_std │ │ --- ┆ --- ┆ --- ┆ --- │ │ date ┆ i64 ┆ f64 ┆ f64 │ ╞════════════╪═══════╪════════════════╪════════════════╡ │ 2023-01-01 ┆ 10 ┆ 10.0 ┆ 0.0 │ │ 2023-01-02 ┆ 20 ┆ 15.0 ┆ 5.0 │ │ 2023-01-03 ┆ 30 ┆ 20.0 ┆ 8.164966 │ │ 2023-01-04 ┆ 40 ┆ 25.0 ┆ 11.18034 │ │ 2023-01-05 ┆ 50 ┆ 30.0 ┆ 14.142136 │ └────────────┴───────┴────────────────┴────────────────┘
二、自定义扩展窗口(复杂场景/分组需求)
如果需要分组后的扩展窗口计算,或者自定义聚合逻辑,可以用over()结合窗口范围定义实现:
分组扩展窗口示例
df_with_groups = pl.DataFrame({ "group": ["A", "A", "B", "B", "A"], "value": [10, 20, 30, 40, 50] }) df_with_groups = df_with_groups.with_columns( pl.col("value").mean().over( # 指定分组列 pl.col("group"), # 定义窗口范围:从分组内第0行到当前行 window=pl.window(range_start=0, range_end=pl.int_range(0, pl.count())) ).alias("group_expanding_mean") ) print(df_with_groups)
输出结果
shape: (5, 3) ┌───────┬───────┬────────────────────┐ │ group ┆ value ┆ group_expanding_mean │ │ --- ┆ --- ┆ --- │ │ str ┆ i64 ┆ f64 │ ╞═══════╪═══════╪════════════════════╡ │ A ┆ 10 ┆ 10.0 │ │ A ┆ 20 ┆ 15.0 │ │ B ┆ 30 ┆ 30.0 │ │ B ┆ 40 ┆ 35.0 │ │ A ┆ 50 ┆ 26.666667 │ └───────┴───────┴────────────────────┘
三、大数据场景:Lazy API支持
如果处理超大数据集,Polars的Lazy API同样支持扩展窗口计算,性能更优:
lazy_df = pl.LazyFrame({ "date": pl.date_range(start="2023-01-01", end="2023-01-05", interval="1d"), "value": [10, 20, 30, 40, 50] }) # 延迟计算,最后collect触发执行 result = lazy_df.with_columns( pl.col("value").cum_mean().alias("expanding_mean"), pl.col("value").cum_std().alias("expanding_std") ).collect()
内容的提问来源于stack exchange,提问作者Nikhilesh Bhagat
相关产品推荐
相关产品推荐

