“DataFrame.rolling”是否在 Polars 中保持顺序?

Does `DataFrame.rolling` preserve order in Polars?

提问人:Ruben 提问时间:11/15/2023 最后编辑:Ruben 更新时间:11/20/2023 访问量:99

问:

将聚合结果重新分配回原始数据帧是否安全,如下所示:DataFrame.rolling

import polars as pl
from datetime import datetime

df = pl.DataFrame(
    {
        "dt": [datetime(2021, 1, 1), datetime(2021, 1, 2), datetime(2021, 1, 4), datetime(2021, 1, 5)],
        "key": ["a", "a", "b", "b"],
        "values": pl.arange(0, 4, eager=True),
        "another_column": ["foo", "bar", "baz", "bla"],
    }
)

result = (
    df.rolling("dt", period="2d", by="key")
    .agg(
        pl.col("values")
        .sum()
        .alias("the_sum")
    )
)

df = df.select([
    pl.all(),
    result.get_column("the_sum")
])

或者你应该重新加入使用 and 列?resultdfdtkey

我尝试了一些玩具示例,这些示例表明可以保持秩序,但是,这并不能保证情况总是如此。DataFrame.rolling

蟒蛇极地

评论


答:

1赞 Ruben 11/16/2023 #1

这样做似乎不安全。反例:

(请注意,默认情况下被视为已排序;这是因为在组排序)dfcheck_sorted=Truedf

import polars as pl
from datetime import datetime

df = (
    pl.DataFrame(
        {
            "dt": [datetime(2021, 1, 1), datetime(2021, 1, 2), datetime(2021, 1, 1), datetime(2021, 1, 2)],
            "key": ["a", "a", "b", "b"],
            "values": pl.arange(0, 4, eager=True),
            "another_column": ["foo", "bar", "baz", "bla"],
        }
    )
    .sort("dt", "key")
)

result = df.rolling("dt", period="1d", by="key").agg(pl.col("values").sum().alias("the_sum"))

df = df.select([
    pl.all(),
    result.get_column("the_sum")
])

print(df)  # we expect "values" to be equal to "the_sum"

┌─────────────────────┬─────┬────────┬────────────────┬─────────┐
│ dt                  ┆ key ┆ values ┆ another_column ┆ the_sum │
│ ---                 ┆ --- ┆ ---    ┆ ---            ┆ ---     │
│ datetime[μs]        ┆ str ┆ i64    ┆ str            ┆ i64     │
╞═════════════════════╪═════╪════════╪════════════════╪═════════╡
│ 2021-01-01 00:00:00 ┆ a   ┆ 0      ┆ foo            ┆ 0       │
│ 2021-01-01 00:00:00 ┆ b   ┆ 2      ┆ baz            ┆ 1       │
│ 2021-01-02 00:00:00 ┆ a   ┆ 1      ┆ bar            ┆ 2       │
│ 2021-01-02 00:00:00 ┆ b   ┆ 3      ┆ bla            ┆ 3       │
└─────────────────────┴─────┴────────┴────────────────┴─────────┘

更新:

一位维护者在 GitHub 上证实,惯用的方法是将结果连接回原始数据帧。因此,在这种情况下,您应该执行以下操作:

df.join(result, how="left", on=["dt", "key"])

评论

0赞 jqurious 11/16/2023
感谢您的跟进。我现在将保留我的答案,但当您发布用于重新添加结果的惯用方法时,我可以将其删除。
1赞 Ruben 11/20/2023
@jqurious好的,谢谢。做!