map_elements
。我还考虑了group_by_dynamic
import polars as pl
import datetime
df = pl.DataFrame({
"time": [
datetime.datetime(2025, 2, 2, 11, 1),
datetime.datetime(2025, 2, 2, 11, 2),
datetime.datetime(2025, 2, 2, 11, 3)
],
"amount": [5.0, -1, 10]
})
dg = pl.DataFrame(
pl.datetime_range(
datetime.datetime(2025, 2, 2, 11, 0),
datetime.datetime(2025, 2, 2, 11, 5),
"1m",
eager = True
),
schema=["time"]
)
def _cumsum(dt):
return df.filter(pl.col("time") <= dt).select(pl.col("amount")).sum().item()
dg.with_columns(
cum_amount=pl.col("time").map_elements(_cumsum, return_dtype= pl.Float64)
)
,但我不确定它可以控制时间网格的启动 /结束 /增量。
df
可以纯粹依靠Polar的天然表达式API来实现这一目标。作为第一步,我们可以将
dg
中的每一行与最早的时间戳相等或比相应的时间戳等级的时间戳记。为此,可以使用
df
。
pl.DataFrame.join_asof
strategy="forward"
next,我们可以加入使用这些时间戳将
Amount
值连接到
df.join_asof(dg, on="time", strategy="forward", coalesce=False)
.。
shape: (3, 3)
┌─────────────────────┬────────┬─────────────────────┐
│ time ┆ amount ┆ time_right │
│ --- ┆ --- ┆ --- │
│ datetime[μs] ┆ f64 ┆ datetime[μs] │
╞═════════════════════╪════════╪═════════════════════╡
│ 2025-02-02 11:01:00 ┆ 5.0 ┆ 2025-02-02 11:01:00 │
│ 2025-02-02 11:02:00 ┆ -1.0 ┆ 2025-02-02 11:02:00 │
│ 2025-02-02 11:03:00 ┆ 10.0 ┆ 2025-02-02 11:03:00 │
└─────────────────────┴────────┴─────────────────────┘
dg
注意,我们在返回的数据框中重命名列,然后合并回dg.join(
(
df
.join_asof(dg, on="time", strategy="forward", coalesce=False)
.select("amount", pl.col("time_right").alias("time"))
),
on="time",
how="left",
)
.。尽管在此示例中未显示,但现在可能会为给定的时间戳重复行(因为与给定的时间戳相关的
shape: (6, 2)
┌─────────────────────┬────────┐
│ time ┆ amount │
│ --- ┆ --- │
│ datetime[μs] ┆ f64 │
╞═════════════════════╪════════╡
│ 2025-02-02 11:00:00 ┆ null │
│ 2025-02-02 11:01:00 ┆ 5.0 │
│ 2025-02-02 11:02:00 ┆ -1.0 │
│ 2025-02-02 11:03:00 ┆ 10.0 │
│ 2025-02-02 11:04:00 ┆ null │
│ 2025-02-02 11:05:00 ┆ null │
└─────────────────────┴────────┘
中可能有多个值)。因此,我们首先汇总了每个时间戳的mount值。然后,我们可以执行常规累积总和。
pl.DataFrame.join_asof
dg