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

如何在Polars DataFrame的SELECT中访问前一行值?Heikin-Ashi蜡烛图计算

问题

我有一个结构如下的DataFrame:

DF = { "open": [], "high":[], "low":[], "close":[] }

需要通过以下公式聚合这个DF:

# OPEN = (Open_n-1 + Close_n-1) / 2.0
# HIGH = Max(High_n, Open_n, Close_n)
# LOW = Min(Low_n, Open_n, Close_n)
# CLOSE = (Open_n + High_n + Low_n + Close_n) / 4.0

我在实现OPEN = (Open_n-1 + Close_n-1) / 2.0这一步遇到了问题,不知道如何访问前一行的值。考虑过逐行遍历或者用额外查询生成前一行占位符,但感觉这种方式不够优雅,希望能得到更合适的实现建议。

目前我已经实现的代码如下:

self.candle_data_ctx.price_candle_df.select([
    # OPEN = (Open_n-1 + Close_n-1) / 2.0
    #     TODO - implement
    # HIGH = Max(High_n, Open_n, Close_n)
    pl.max([pl.col('high_price'), pl.col('open_price'), pl.col('close_price')
                ]).alias('high_price'),
    # LOW = Min(Low_n, Open_n, Close_n)
    pl.min([pl.col('low_price'), pl.col('open_price'), pl.col('close_price')
                ]).alias('low_price'),
    # CLOSE = (Open_n + High_n + Low_n + Close_n) / 4.0
    (
       (
          pl.col('open_price') + pl.col('high_price') + pl.col('low_price') + pl.col('close_price')
        ) / 4.0
    ).alias('close_price'),
])
解决方案

在Polars中,直接用shift()方法就能获取前一行的数据,完全不需要逐行遍历或者额外查询,代码会非常简洁优雅。

针对OPEN字段的实现,你可以这样写:

(pl.col('open_price').shift(1) + pl.col('close_price').shift(1)) / 2.0

shift(1)表示将当前列向下偏移1位,也就是取前一行的值。

下面是完整的实现代码:

self.candle_data_ctx.price_candle_df.select([
    # OPEN = (Open_n-1 + Close_n-1) / 2.0
    ((pl.col('open_price').shift(1) + pl.col('close_price').shift(1)) / 2.0).alias('open_price'),
    # HIGH = Max(High_n, Open_n, Close_n)
    pl.max([pl.col('high_price'), pl.col('open_price'), pl.col('close_price')]).alias('high_price'),
    # LOW = Min(Low_n, Open_n, Close_n)
    pl.min([pl.col('low_price'), pl.col('open_price'), pl.col('close_price')]).alias('low_price'),
    # CLOSE = (Open_n + High_n + Low_n + Close_n) / 4.0
    ((pl.col('open_price') + pl.col('high_price') + pl.col('low_price') + pl.col('close_price')) / 4.0).alias('close_price'),
])

需要注意的是,第一行的open_price会因为没有前一行数据而得到null,如果需要处理这个情况,可以用fill_null()方法来填充默认值,比如:

((pl.col('open_price').shift(1) + pl.col('close_price').shift(1)) / 2.0).fill_null(pl.col('open_price')).alias('open_price')

这样第一行会直接使用当前行的open_price作为默认值,你可以根据实际需求调整填充逻辑。

内容的提问来源于stack exchange,提问作者Joris Medeišis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 14:28:01