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

在Polars中使用diff或shift时如何忽略前置空值?

分组内计算当前值与前一个非空值的差值

需求是在分组内,计算当前值与前一个非空值的差值。从id和value列出发,想要生成result列,示例如下:

idvalueresult说明
a10null10 - 无前置非空值
anullnullnull 与前置值无法计算差值
a302030 - 10
b5null5 - 无前置非空值
b10510 - 5
bnullnullnull 与前置值无法计算差值
bnullnullnull 与前置值无法计算差值
b403040 - 10

背景说明

这是填充空值的中间步骤,最终目标是填充空值,但并非线性填充——因为每行带有时间戳,需要根据行之间的时间差分配两个非空值的差值。例如,对于"a"分组:第一行与第二行时间差为10秒,第二行与第三行时间差为30秒,那么差值20应分配为:第二行填充值为10 + 20*(10/40),第三行填充值为10 + 20*(30/40)。

尝试的代码及问题

最初在Polars中尝试以下代码:

import polars as pl

df = pl.DataFrame({
        "id": ["a", "a", "a", "b", "b", "b", "b", "b"],
        "value": [10, None, 30, 5, 10, None, None, 40]
})

df_delta = df.with_columns(
    delta = pl.col("value").diff(1).over("id"),
    delta_ignore = pl.col("value").diff(1, null_behavior="ignore").over("id")
)

其中第二列使用了null_behavior="ignore"参数,但得到的结果不符合预期:

idvaluedeltadelta_ignore
a10nullnull
anullnullnull
a30nullnull
b5nullnull
b1055
bnullnullnull
bnullnullnull
b40nullnull

解决方法

通过扩展窗口分区的方法解决了问题,代码如下:

df.with_columns(
    delta = pl.col("value").diff(1).over("id", pl.col("value").is_not_null())
)

得到的结果符合预期:

idvaluedelta
a10null
anullnull
a3020
b5null
b105
bnullnull
bnullnull
b4030

内容的提问来源于stack exchange,提问作者Wouter De Raeve

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:55:29