如何在Polars的group_by_dynamic后添加非日期时间二级分组
在Polars中结合动态时间分组与非时间字段二级分组
问题描述
需要将数据按小时/日/周的时间间隔分组,同时按其他指定字段(如Channel)进一步分组。已通过Polars的group_by_dynamic实现时间间隔分组,现需添加非日期时间类型的二级分组字段。
示例DataFrame
import polars as pl df = pl.from_repr(""" ┌─────────────────────┬──────────┬────────┬─────────┬──────────┐ │ Date ┆ Item ┆ Issue ┆ Channel ┆ ID │ │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ │ datetime[μs] ┆ str ┆ str ┆ str ┆ i64 │ ╞═════════════════════╪══════════╪════════╪═════════╪══════════╡ │ 2023-01-02 01:40:00 ┆ Item ABC ┆ ASDFFF ┆ Web ┆ 32513995 │ │ 2023-01-02 02:15:00 ┆ Item ABC ┆ WERWET ┆ Web ┆ 32513995 │ │ 2023-01-02 03:00:00 ┆ Item ABC ┆ BVRTNB ┆ Twitter ┆ 32513995 │ │ 2023-01-03 04:11:00 ┆ Item ABC ┆ VDFGVS ┆ Fax ┆ 32513995 │ │ 2023-01-03 04:30:00 ┆ Item ABC ┆ QWEDWE ┆ Twitter ┆ 32513995 │ │ 2023-01-03 04:45:00 ┆ Item ABC ┆ BRHMNU ┆ Fax ┆ 32513995 │ └─────────────────────┴──────────┴────────┴─────────┴──────────┘ """)
当前实现代码(仅时间分组)
import polars as pl q = ( pl.scan_csv("Test.csv", try_parse_dates=True) .filter(pl.col("Item") == "Item ABC") .group_by_dynamic("Date", every="1h", closed="right") .agg(pl.col("ID").count().alias("total")) .sort("Date") ) df = q.collect()
当前结果
┌─────────────────────┬───────┐ │ Date ┆ total │ ╞═════════════════════╪═══════╡ │ 2023-01-02 01:00:00 ┆ 2 │ │ 2023-01-02 02:00:00 ┆ 1 │ │ 2023-01-02 03:00:00 ┆ 1 │ │ 2023-01-03 04:00:00 ┆ 3 │ └─────────────────────┴───────┘
期望结果(按Channel二级分组)
┌─────────────────────┬─────────┬───────┐ │ Date ┆ Channel ┆ total │ ╞═════════════════════╪═════════╪═══════╡ │ 2023-01-02 01:00:00 ┆ Web ┆ 1 │ │ 2023-01-02 02:00:00 ┆ Web ┆ 1 │ │ 2023-01-02 03:00:00 ┆ Twitter ┆ 1 │ │ 2023-01-03 04:00:00 ┆ Fax ┆ 2 │ │ 2023-01-03 04:00:00 ┆ Twitter ┆ 1 │ └─────────────────────┴─────────┴───────┘
解决方案
Polars的group_by_dynamic方法内置了by参数,可直接传入需要二级分组的非时间字段,无需额外执行分组操作。
修改后的代码
import polars as pl q = ( pl.scan_csv("Test.csv", try_parse_dates=True) .filter(pl.col("Item") == "Item ABC") # 通过by参数指定二级分组字段Channel .group_by_dynamic("Date", every="1h", closed="right", by="Channel") .agg(pl.col("ID").count().alias("total")) # 同时按Date和Channel排序,让结果更规整 .sort(["Date", "Channel"]) ) df = q.collect()
关键说明
by参数支持单个字段名或字段列表(如by=["Channel", "Item"]),可实现多字段的二级分组- 排序时同时指定时间字段和分组字段,能让结果的展示逻辑更清晰
内容的提问来源于stack exchange,提问作者Vifula
相关产品推荐
相关产品推荐

