如何计算 Polars 中的滚动统计数据,从“end_date”开始回顾?

问题描述 投票:0回答:1

我想计算金融数据时间序列的滚动

"1m"
统计数据。鉴于每月计算的行数并不总是相等,除非您有足够的数据来划分月份,而这种情况并不常见。

我正在尝试分配一列

window_index
来跟踪计算中包含的行,因为我将使用
.rolling().over()
表达式来计算每个窗口上的统计数据。我希望从最新日期开始添加
window_index
整数,并按顺序返回。

这里有一张图片可以帮助解释:

目前,我想做的是将

window_index
添加到由红色和蓝色笔表示的组中。虽然我希望数据按黄色笔标记进行分组。数据集以
2023-02-07
结束,一个月前为
2023-01-07
,或最接近的值
2023-01-06

这是我用来实现此目的的代码,但我不确定如何获得我想要的分组窗口。

df_window_index = (
    data.group_by_dynamic(
        index_column="date", every="1m", by="symbol"
    )
    .agg()
    .with_columns(
        pl.int_range(0, pl.len()).over("symbol").alias("window_index")
    )
)
data = data.join_asof(df_window_index, on="date", by="symbol").sort(
    "symbol"
)

使用

timedelta
代替字符串似乎无法解决问题。

左边是上面的代码,右边的图片是我制作

every=timedelta(days=31)
时的图像。我仍然不明白为什么 Polars 将这些日期拉至 31 天的时间增量。

任何帮助,或者任何提示我正确的方向,我们将不胜感激!谢谢!

数据:

df = pl.read_csv(b"""
date,open,high,low,close,volume,dividends,stock_splits,symbol,window_index
2021-01-04T00:00:00.000000000,133.52,133.61,126.76,129.41,143301900,0.0,0.0,AAPL,0
2021-01-05T00:00:00.000000000,128.89,131.74,128.43,131.01,97664900,0.0,0.0,AAPL,0
2021-01-06T00:00:00.000000000,127.72,131.05,126.38,126.6,155088000,0.0,0.0,AAPL,0
2021-01-07T00:00:00.000000000,128.36,131.63,127.86,130.92,109578200,0.0,0.0,AAPL,1
2021-01-08T00:00:00.000000000,132.43,132.63,130.23,132.05,105158200,0.0,0.0,AAPL,1
2021-01-11T00:00:00.000000000,129.19,130.17,128.5,128.98,100384500,0.0,0.0,AAPL,1
2021-01-12T00:00:00.000000000,128.5,129.69,126.86,128.8,91951100,0.0,0.0,AAPL,1
2021-01-13T00:00:00.000000000,128.76,131.45,128.49,130.89,88636800,0.0,0.0,AAPL,1
2021-01-14T00:00:00.000000000,130.8,131.0,128.76,128.91,90221800,0.0,0.0,AAPL,1
2021-01-15T00:00:00.000000000,128.78,130.22,127.0,127.14,111598500,0.0,0.0,AAPL,1
2021-01-19T00:00:00.000000000,127.78,128.71,126.94,127.83,90757300,0.0,0.0,AAPL,1
2021-01-20T00:00:00.000000000,128.66,132.49,128.55,132.03,104319500,0.0,0.0,AAPL,1
2021-01-21T00:00:00.000000000,133.8,139.67,133.59,136.87,120150900,0.0,0.0,AAPL,1
2021-01-22T00:00:00.000000000,136.28,139.85,135.02,139.07,114459400,0.0,0.0,AAPL,1
2021-01-25T00:00:00.000000000,143.07,145.09,136.54,142.92,157611700,0.0,0.0,AAPL,1
2021-01-26T00:00:00.000000000,143.6,144.3,141.37,143.16,98390600,0.0,0.0,AAPL,1
2021-01-27T00:00:00.000000000,143.43,144.3,140.41,142.06,140843800,0.0,0.0,AAPL,1
2021-01-28T00:00:00.000000000,139.52,141.99,136.7,137.09,142621100,0.0,0.0,AAPL,1
2021-01-29T00:00:00.000000000,135.83,136.74,130.21,131.96,177523800,0.0,0.0,AAPL,1
2021-02-01T00:00:00.000000000,133.75,135.38,130.93,134.14,106239800,0.0,0.0,AAPL,1
2021-02-02T00:00:00.000000000,135.73,136.31,134.61,134.99,83305400,0.0,0.0,AAPL,1
2021-02-03T00:00:00.000000000,135.76,135.77,133.61,133.94,89880900,0.0,0.0,AAPL,1
2021-02-04T00:00:00.000000000,136.3,137.4,134.59,137.39,84183100,0.0,0.0,AAPL,1
2021-02-05T00:00:00.000000000,137.35,137.42,135.86,136.76,75693800,0.2,0.0,AAPL,1
""".strip(), try_parse_dates=True)
python python-3.x python-polars date-arithmetic rolling-computation
1个回答
0
投票

要标记从每组中的最新日期开始向后追溯的不重叠的 1 个月时间窗口,您可以使用以下辅助函数。

def create_1m_window_index(col):
    year_diff = pl.col(col).last().dt.year() - pl.col(col).dt.year()
    month_diff = pl.col("date").last().dt.month() - pl.col("date").dt.month()
    day_indicator = pl.col("date").dt.day() > pl.col("date").last().dt.day()
    return 12 * year_diff + month_diff - day_indicator

可以按如下方式使用。

df.with_columns(create_1m_window_index("date").alias("window_index").over("group"))

请注意,任意时间窗口的一般情况更为复杂(如我的评论中所述)。

© www.soinside.com 2019 - 2024. All rights reserved.