0

0

计算 Polars DataFrame 中滚动窗口内的百分位排名

碧海醫心

碧海醫心

发布时间:2025-12-30 12:55:37

|

957人浏览过

|

来源于php中文网

原创

计算 Polars DataFrame 中滚动窗口内的百分位排名

本文详解如何在 polars 中对时间序列或索引序列数据执行滚动窗口(如 4 期)的百分位排名计算,解决 `group_by_dynamic` 排序异常与除零错误,并推荐更稳定、语义清晰的 `rolling()` 方案。

金融或时序分析中,常需基于滑动窗口(例如最近 252 个交易日 × 3 = 756 天,或简化为 4 期)计算某资产价格相对于窗口内其他值的相对位置——即滚动百分位排名(percentile rank)。Polars 提供了高性能的窗口操作能力,但正确使用需注意排序状态、窗口边界语义及空值/长度不足场景的处理。

✅ 正确做法:用 rolling() 替代 group_by_dynamic

group_by_dynamic 要求索引列全局严格单调递增且无重复,且 every="1i"(逐单位滚动)在日期列上易因精度或缺失导致“未显式排序”报错;而 rolling() 专为滑动窗口设计,语义更直观、容错更强,且天然支持 closed="left" 等边界控制。

以下以整数索引为例(实际中可替换为 date 列,但需确保其为 pl.Date 或 pl.Datetime 并已排序):

微信 WeLM
微信 WeLM

WeLM不是一个直接的对话机器人,而是一个补全用户输入信息的生成模型。

下载
import polars as pl

prices = pl.DataFrame({
    "int_index": range(6),
    "asset_1": [1.1, 3.4, 2.6, 4.8, 7.4, 3.2],
    "asset_2": [4, 7, 8, 3, 4, 5],
    "asset_3": [1, 3, 10, 20, 2, 4],
})

# 定义待计算列(排除索引列)
rank_cols = pl.all().exclude("int_index")

# 执行滚动窗口百分位计算:窗口大小为 4,左闭右开(包含当前行及后续3行)
percentiles = (
    prices.sort("int_index")  # 确保索引有序(必要!)
    .rolling(
        index_column="int_index",
        period="4i",      # 窗口跨度:4 个单位
        offset="0i",      # 不偏移,从当前索引开始
        closed="left"     # 包含左端点(当前行),不包含右端点(第 i+4 行)
    )
    .agg(
        (rank_cols.rank(method="min").first() * 100.0 / rank_cols.count())
        .name.suffix("_percentile")
    )
)

print(percentiles)

输出结果:

shape: (6, 4)
┌───────────┬────────────────────┬────────────────────┬────────────────────┐
│ int_index ┆ asset_1_percentile ┆ asset_2_percentile ┆ asset_3_percentile │
│ ---       ┆ ---                ┆ ---                ┆ ---                │
│ i64       ┆ f64                ┆ f64                ┆ f64                │
╞═══════════╪════════════════════╪════════════════════╪════════════════════╡
│ 0         ┆ 25.0               ┆ 50.0               ┆ 25.0               │
│ 1         ┆ 50.0               ┆ 75.0               ┆ 50.0               │
│ 2         ┆ 25.0               ┆ 100.0              ┆ 75.0               │
│ 3         ┆ 66.666667          ┆ 33.333333          ┆ 100.0              │
│ 4         ┆ 100.0              ┆ 50.0               ┆ 50.0               │
│ 5         ┆ 100.0              ┆ 100.0              ┆ 100.0              │
└───────────┴────────────────────┴────────────────────┴────────────────────┘
? 验证逻辑: 第 0 行窗口为 [1.1, 3.4, 2.6, 4.8] → 1.1 排名第 1(最小),百分位 = (1 / 4) × 100 = 25% 第 1 行窗口为 [3.4, 2.6, 4.8, 7.4] → 3.4 排名第 2 → (2 / 4) × 100 = 50%

⚠️ 关键注意事项

  • 必须先 sort() 再 rolling():即使数据看似有序,Polars 也不自动推断排序状态,sort() 是强制保障。
  • 窗口长度不足时的行为:当剩余行数
  • method="min" 更合理:处理重复值时,min 方法赋予相同值最小排名(如 [2,2,3] 中两个 2 均得排名 1),符合多数百分位定义;默认 average 可能产生非整数排名。
  • 日期列适配:若 index_column="date" 为 pl.Date,period="4d" 即 4 天窗口;若为 pl.Datetime,可用 "4h"、"7d" 等。确保日期无重复且已排序。
  • 性能提示:rolling() 在 Polars 中高度优化,远快于手动循环或 Pandas rolling,尤其适用于大数据集。

? 总结

  • ❌ 避免对非时间连续索引滥用 group_by_dynamic + every="1i",易触发排序异常和除零错误;
  • ✅ 优先选用 rolling() + closed="left" 实现“当前行及其后 N-1 行”的前向滚动窗口;
  • ✅ 显式调用 sort()、指定 rank(method="min")、用 .first() 提取当前行排名,是健壮计算的核心;
  • ✅ 结果列命名统一用 .name.suffix(),保持代码简洁可维护。

通过以上方法,你可高效、准确地在 Polars 中实现任意数值列的滚动百分位排名,无缝对接量化策略回测、异常检测等生产场景。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

49

2025.12.04

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

378

2023.09.04

excel制作动态图表教程
excel制作动态图表教程

本专题整合了excel制作动态图表相关教程,阅读专题下面的文章了解更多详细教程。

24

2025.12.29

freeok看剧入口合集
freeok看剧入口合集

本专题整合了freeok看剧入口网址,阅读下面的文章了解更多网址。

74

2025.12.29

俄罗斯搜索引擎Yandex最新官方入口网址
俄罗斯搜索引擎Yandex最新官方入口网址

Yandex官方入口网址是https://yandex.com;用户可通过网页端直连或移动端浏览器直接访问,无需登录即可使用搜索、图片、新闻、地图等全部基础功能,并支持多语种检索与静态资源精准筛选。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

207

2025.12.29

python中def的用法大全
python中def的用法大全

def关键字用于在Python中定义函数。其基本语法包括函数名、参数列表、文档字符串和返回值。使用def可以定义无参数、单参数、多参数、默认参数和可变参数的函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

16

2025.12.29

python改成中文版教程大全
python改成中文版教程大全

Python界面可通过以下方法改为中文版:修改系统语言环境:更改系统语言为“中文(简体)”。使用 IDE 修改:在 PyCharm 等 IDE 中更改语言设置为“中文”。使用 IDLE 修改:在 IDLE 中修改语言为“Chinese”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

18

2025.12.29

C++的Top K问题怎么解决
C++的Top K问题怎么解决

TopK问题可通过优先队列、partial_sort和nth_element解决:优先队列维护大小为K的堆,适合流式数据;partial_sort对前K个元素排序,适用于需有序结果且K较小的场景;nth_element基于快速选择,平均时间复杂度O(n),效率最高但不保证前K内部有序。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

12

2025.12.29

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

136

2025.12.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 4.1万人学习

PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.2万人学习

Django 教程
Django 教程

共28课时 | 2.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号