Polars - 如何提取给定列上的最后一个非空值

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

我想执行以下操作:

输入:

df = pl.DataFrame({
    "a": [1,15,None,20,None]
})

输出:

df = pl.DataFrame({
    "a": [1,15,None,20,None],
    "b": [0,14,None,5,None]
})

也就是说,来自:

A
1
15
20

至:

A B
1 0
15 14
20 5

那么,它的作用是:

  1. 如果“A”的值为空,则B(输出列)的值也为空
  2. 如果“A”有某个值,请检索“A”中最后一个非空值,然后用前一个非空值减去“A”中的当前值

我想在Python的极坐标数据框库中执行此操作,但我似乎找不到解决方案。

我尝试过以下问题:

如何从Polars中的一列中选择最后一个非空值以及同一行上另一列的值?

但不幸的是,这并不能回答原来的问题,因为该问题执行整个列的聚合,然后获取该列的最后一个值。

我想做的不是聚合整个列,而是简单地用先前的非空值减去当前值。

我也尝试过使用滚动:

df = df.with_row_index().rolling(
    index_column = 'index',
    period = '???i').agg(pl.col("A").last())

但是,当然,这不起作用,因为无法确定空值的出现(即它不是周期性的,所以我不知道当前条目之前有多少个索引包含“A”中的非空值) .

有谁知道怎么做吗?

谢谢!

python null python-polars rolling-computation
1个回答
0
投票

您可以使用

shift
forward_fill
的组合来获取最后一个非空值。

根据您的输入,这看起来像

df = pl.DataFrame({
    "a": [1, 15, None, 20, None]
})
df.with_columns(
    pl.when(pl.col("a").is_not_null())
    # current row value for "a" minus the last non-null value
    # as the first row has no previous non-null value, fill it with 0
    # (per your expected output)
    .then((pl.col("a") - pl.col("a").shift().forward_fill()).fill_null(0))
    # no otherwise block means any rows not meeting the when condition get null
    .alias("b")
)
# shape: (5, 2)
# ┌──────┬──────┐
# │ a    ┆ b    │
# │ ---  ┆ ---  │
# │ i64  ┆ i64  │
# ╞══════╪══════╡
# │ 1    ┆ 0    │
# │ 15   ┆ 14   │
# │ null ┆ null │
# │ 20   ┆ 5    │
# │ null ┆ null │
# └──────┴──────┘
© www.soinside.com 2019 - 2024. All rights reserved.