Polars 时间序列操作指南
Polars 为时间序列重采样提供了强大的方法支持。许多人都知道 Pandas 中 df.resample
提供了重采样功能。
上采样 (Up Sampling)
上采样实际上相当于将一个日期范围与你的数据集进行左关联 (left join) 操作,并填充缺失数据。Polars 为此操作 提供了封装方法,你可以参考下面的一个示例。
df = pl.DataFrame(
{
"time": pl.date_range(start=datetime(2021, 12, 16), end=datetime(2021, 12, 16, 3), interval="30m", eager=True),
"groups": ["a", "a", "a", "b", "b", "a", "a"],
"values": [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0],
}
)
out1 = df.upsample(time_column="time", every="15m").fill_null(strategy="forward")
out2 = df.upsample(time_column="time", every="15m").interpolate().fill_null(strategy="forward")
下采样 (Down Sampling)
下采样很有意思。你需要处理日期间隔、窗口持续时间、聚合等问题。Polars 将下采样视为分组 (groupby) 操作的一个特例,因此表达式 API 为分组上下文 (contexts) 提供了两个额外的入口。
df = pl.DataFrame(
{
"time": pl.date_range(
start=datetime(2021, 12, 16),
end=datetime(2021, 12, 16, 3),
interval="30m",
eager=True,
),
"groups": ["a", "a", "a", "b", "b", "a", "a"],
}
)
out = df.groupby_dynamic(
"time",
every="1h",
closed="both",
by="groups",
include_boundaries=True,
).agg([pl.count()])
动态分组 (Groupby Dynamic)
在下面的一段代码中,我们以天 ("1d"
) 为单位,把关于 2021 年的日期范围 (date range) 创建为一个 DataFrame。
接下来,我们创建起始于每月 ("1mo"
),长度为 1
个月的动态窗口 (dynamic windows)。动态窗口的大小并不由 DataFrame 中的行数决定,而是由一个时间单位 (temporal unit) 决定,比如一天 ("1d"
),三周 ("3w"
),亦或是五纳秒 ("5ns"
) … 希望这个例子有助于让你理解动态窗口的含义。
匹配某个动态窗口的值会被分配到该窗口所对应的组中,接下来你可以用强大的表达式方法进行聚合操作。
# 时间轴(从low到high,间隔为1天,轴名称为"time")
df = pl.date_range(start=datetime(2021, 1, 1),
end=datetime(2021, 12, 31),
interval="1d",
name="time",
eager=True).to_frame()
out = (
df.groupby_dynamic("time", every="1mo", period="1mo", closed="left")
.agg(
[
pl.col("time").cumcount().reverse().head(3).alias("day/eom"),
((pl.col("time") - pl.col("time").first()).last().dt.days() + 1).alias("days_in_month"),
]
)
.explode("day/eom")
)
print(out)
要定义一个动态窗口,需要提供以下三个参数:
- every:窗口的时间间隔
- period:窗口的持续时间
- offset:可以对窗口的开始