Pandas分组滚动聚合代码转Polars时遇类型错误求助
Pandas滚动聚合转Polars的问题解决
问题描述
要将这段Pandas滚动聚合代码转换为Polars:
df.groupby(groupby_col)[[A_col, B_col]].rolling(window=window, on=B_col, closed = 'left').agg(some_function)
其中A_col是Int64类型,B_col是datetime(ns)类型。
自己写的Polars代码如下:
df.group_by(groupby_col).agg(pl.col([A_col, B_col])).with_columns( pl.col([A_col, B_col]).rolling_mean(window_size=30, by=B_col, closed="left"))
运行后触发错误:
`expr_name` operation not supported for dtype `list[date]` (expected: date/datetime)
疑问:为什么rolling_mean的by参数不能接受日期列表?
解决方案
问题出在你的Polars写法逻辑错误:group_by().agg(pl.col([A_col, B_col]))会把每组的A_col和B_col转换成列表类型,但Polars的滚动函数要求处理的是原始的标量列,不是列表,这就是报错的根源。
正确写法思路
不需要先agg把列打包成列表,直接在分组后对目标列调用滚动函数即可:
对应原Pandas自定义聚合的写法
如果some_function是自定义聚合逻辑,用rolling()配合agg():
df.group_by(groupby_col).agg( # 对A_col按B_col的时间窗口做自定义聚合 pl.col(A_col).rolling( window_size=window, # 时间窗口要写字符串格式,比如"30d"代表30天 by=B_col, closed="left" ).agg(some_function).alias(f"{A_col}_agg_result"), # 按需保留B_col或其他列 pl.col(B_col) )
针对滚动均值的简化写法
如果只是计算均值,直接用rolling_mean,注意时间窗口的格式:
df.group_by(groupby_col).agg( pl.col(A_col).rolling_mean( window_size="30d", # 替换成你实际需要的时间窗口,比如"1w"表示一周 by=B_col, closed="left" ).alias(f"{A_col}_rolling_mean"), pl.col(B_col) )
关键注意点
- Polars分组后直接对原始列调用滚动函数即可,滚动逻辑会自动在每组内基于
by指定的时间列计算窗口,不需要先把列转成列表。 - 时间窗口的
window_size必须用时间字符串(如"1h"、"7d"),如果写数字,Polars会把它当成行数量窗口,这和Pandas的window参数行为不同,别搞混。
内容的提问来源于stack exchange,提问作者Alessandro Togni
相关产品推荐
相关产品推荐

