Polars中DataFrame.rolling是否保留顺序?聚合结果如何安全回写?
Polars中rolling的行顺序与列添加的安全性问题
1. DataFrame.rolling是否保留原数据顺序?
- 当使用
by分组并指定time_column(如示例中的dt)时,Polars会先对每个分组内的数据按时间列排序,再计算滚动窗口。 - 输出结果的行顺序:
- 如果原DataFrame的每个分组内已经按时间列严格排序,
rolling的输出行顺序会和原DataFrame一致; - 如果原分组内时间列是乱序的,
rolling的输出行顺序会是分组内排序后的顺序,和原DataFrame的行顺序不一致。
- 如果原DataFrame的每个分组内已经按时间列严格排序,
2. 直接用select添加result列是否安全?
这种做法不安全,属于依赖巧合的写法:只有当原数据分组内时间完全有序时才会正确,一旦原数据分组内时间乱序,rolling输出的行顺序会和原DataFrame错位,导致聚合值和原行不匹配。
正确的实现方式
推荐两种更可靠的写法:
方式1:直接在原DataFrame中用with_columns生成列
无需单独生成result,Polars会自动处理行匹配,无论原数据是否排序:
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"], } ) df = df.with_columns( pl.col("values") .rolling("dt", period="2d", by="key") .sum() .alias("the_sum") )
方式2:通过join连接结果(适合需要单独处理result的场景)
基于key和dt作为唯一标识进行连接,确保聚合值精准匹配原行:
result = df.rolling("dt", period="2d", by="key").agg(pl.col("values").sum().alias("the_sum")) df = df.join(result, on=["key", "dt"], how="left")
内容的提问来源于stack exchange,提问作者Ruben
相关产品推荐
相关产品推荐

