Polars中仅针对负值的滚动标准差计算:日变动分析
解决方案:Polars中计算仅针对负值的滚动标准差
针对你在2500万行分组Polars DataFrame中计算仅负值的30天滚动标准差的需求,可以通过rolling_apply自定义窗口计算逻辑实现,以下是具体步骤和优化方案:
1. 先完成基础指标计算(日变动、日变动百分比)
首先确保已按category分组并计算好日变动及变动百分比:
# 按品类分组后计算日变动与变动百分比 df = df.group_by("category").agg( pl.col("Date").sort(), pl.col("number").sort(), pl.col("number").diff().alias("daily_variation"), (pl.col("number").diff() / pl.col("number").shift()).alias("daily_variation_pct") ).explode(["Date", "number", "daily_variation", "daily_variation_pct"])
2. 自定义滚动窗口函数实现负值标准差
利用rolling_apply对每个滚动窗口内的数据筛选负值后计算标准差:
# 定义筛选负值并计算标准差的函数 def neg_rolling_std(window: pl.Series) -> float: neg_vals = window.filter(window < 0) return neg_vals.std() if len(neg_vals) >= 1 else None # 应用到分组数据,同时计算常规滚动标准差 df = df.group_by("category").with_columns( pl.col("daily_variation_pct").rolling_std(window_size=30).alias("rolling_std_30d"), pl.col("daily_variation_pct").rolling_apply( window_size=30, function=neg_rolling_std, return_dtype=pl.Float64 ).alias("rolling_std_30d_neg") )
3. 大数据集性能优化
由于你的数据量达2500万行,纯Python自定义函数可能存在性能瓶颈,推荐用numba加速计算:
from numba import jit import numpy as np # 用numba编译的向量化函数,大幅提升速度 @jit(nopython=True) def numba_neg_std(arr: np.ndarray) -> float: neg_vals = arr[arr < 0] if len(neg_vals) == 0: return np.nan return np.std(neg_vals, ddof=1) # ddof=1与Polars默认的样本标准差一致 # 应用加速后的函数 df = df.group_by("category").with_columns( pl.col("daily_variation_pct").rolling_apply( window_size=30, function=lambda s: numba_neg_std(s.to_numpy()), return_dtype=pl.Float64 ).alias("rolling_std_30d_neg") )
关键说明
- 若滚动窗口内无负值,函数返回
None或np.nan,符合统计逻辑 rolling_apply必须指定return_dtype,Polars无法自动推断自定义函数的返回类型- Numba加速后的函数性能比纯Python版本提升数倍,适合处理千万级别的大数据量
内容的提问来源于stack exchange,提问作者Luciano
相关产品推荐
相关产品推荐

