如何在Python Polars中对多列执行多聚合操作?
Polars group_by_dynamic 多列多聚合避免DuplicateError的解决方案
出现DuplicateError的核心原因是:循环生成聚合表达式时,不同列的同类型聚合(比如均值、计数)会使用相同的默认列名(如mean、count),导致列名重复冲突。以下是符合Polars风格的解决方案,无需循环或避免列名冲突:
1. 显式指定聚合列别名(最直观)
针对需要聚合的列,为每个聚合结果生成唯一的别名,避免名称冲突:
import polars as pl import numpy as np # 构造测试数据 df = pl.DataFrame({ "timestamp": pl.date_range(start="2023-01-01", end="2023-01-02", interval="1h"), "col1": np.random.rand(25), "col2": np.random.rand(25), "col3": np.random.rand(25) }) # 指定要聚合的列 cols_to_agg = ["col1", "col2", "col3"] # 批量生成带唯一别名的聚合表达式 agg_exprs = [ pl.col(col).mean().alias(f"{col}_mean"), pl.col(col).count().alias(f"{col}_count") for col in cols_to_agg ] # 执行动态分组聚合 result = df.group_by_dynamic("timestamp", every="6h").agg(agg_exprs) print(result)
2. 用struct打包聚合后unnest(更简洁)
通过pl.struct将目标列打包,聚合后用unnest展开,自动生成带前缀的列名:
result = df.group_by_dynamic("timestamp", every="6h").agg( # 对打包的列求均值,结果命名为mean pl.struct(cols_to_agg).mean().alias("mean"), # 对打包的列计数,结果命名为count pl.struct(cols_to_agg).count().alias("count") ).unnest("mean", "count") # 展开struct列,生成col1_mean、col1_count等列 print(result)
3. 批量处理所有目标列(无需枚举列名)
如果需要对除时间列外的所有数值列做聚合,可用pl.all()结合suffix批量生成唯一列名:
result = df.group_by_dynamic("timestamp", every="6h").agg( # 对所有非时间列求均值,添加_mean后缀 pl.all().exclude("timestamp").mean().suffix("_mean"), # 对所有非时间列计数,添加_count后缀 pl.all().exclude("timestamp").count().suffix("_count") ) print(result)
以上方案均遵循Polars的向量化表达式设计原则,避免了循环导致的列名冲突,同时保持代码简洁高效。
内容的提问来源于stack exchange,提问作者FObersteiner
相关产品推荐
相关产品推荐

