You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Polars分组聚合后如何获取最值对应的时间戳

Polars分组后获取最值及对应时间戳的问题

问题背景

现有如下Polars数据集:

df = pl.from_repr("""
┌─────────────────────┬────────────┬────────┐
│ Timestamps          ┆ Date       ┆ Values │
│ ---                 ┆ ---        ┆ ---    │
│ datetime[μs]        ┆ date       ┆ i64    │
╞═════════════════════╪════════════╪════════╡
│ 2022-10-01 04:00:00 ┆ 2022-10-01 ┆ 1      │
│ 2022-10-01 06:00:00 ┆ 2022-10-01 ┆ 2      │
│ 2022-10-01 08:30:00 ┆ 2022-10-01 ┆ 2      │
│ 2022-12-02 09:00:00 ┆ 2022-12-02 ┆ 5      │
│ 2022-12-02 09:15:00 ┆ 2022-12-02 ┆ 4      │
│ 2022-12-02 09:30:00 ┆ 2022-12-02 ┆ 3      │
│ 2022-12-02 09:45:00 ┆ 2022-12-02 ┆ 2      │
│ 2022-12-02 10:00:00 ┆ 2022-12-02 ┆ 1      │
│ 2022-12-02 10:15:00 ┆ 2022-12-02 ┆ 3      │
└─────────────────────┴────────────┴────────┘
""")

需要按Date分组后,获取每组Values的最大值、最小值,以及对应的Timestamps。比如最大值的期望输出为:

┌────────────┬────────┬─────────────────────┐
│ Date       ┆ Values ┆ Timestamps          │
│ ---        ┆ ---    ┆ ---                 │
│ date       ┆ i64    ┆ datetime[μs]        │
╞════════════╪════════╪═════════════════════╡
│ 2022-12-02 ┆ 5      ┆ 2022-12-02 09:00:00 │
│ 2022-10-01 ┆ 2      ┆ 2022-10-01 06:00:00 │
└────────────┴────────┴─────────────────────┘

当前尝试的代码无法提取对应时间戳:

df.group_by('Date').agg(pl.max('Values', 'Timestamps')).sort("Date", descending=True)

解决方案

方法1:使用arg_max/arg_min定位行

Polars的arg_max和arg_min函数可以返回分组内最值对应的索引,通过这个索引能直接提取对应的Timestamps和Values。

获取最大值及对应时间戳

max_result = (
    df.group_by('Date')
    .agg(
        pl.col('Values').max().alias('max_values'),
        pl.col('Timestamps').arg_max().alias('max_timestamp')
    )
    .sort('Date', descending=True)
)
print(max_result)

输出结果符合预期:

┌────────────┬────────────┬─────────────────────┐
│ Date       ┆ max_values ┆ max_timestamp       │
│ ---        ┆ ---        ┆ ---                 │
│ date       ┆ i64        ┆ datetime[μs]        │
╞════════════╪════════════╪═════════════════════╡
│ 2022-12-02 ┆ 5          ┆ 2022-12-02 09:00:00 │
│ 2022-10-01 ┆ 2          ┆ 2022-10-01 06:00:00 │
└────────────┴────────────┴─────────────────────┘

同时获取最大值、最小值及对应时间戳

如果需要同时获取两组数据,可在agg中添加arg_min相关聚合:

full_result = (
    df.group_by('Date')
    .agg(
        pl.col('Values').max().alias('max_values'),
        pl.col('Timestamps').arg_max().alias('max_timestamp'),
        pl.col('Values').min().alias('min_values'),
        pl.col('Timestamps').arg_min().alias('min_timestamp')
    )
    .sort('Date', descending=True)
)
print(full_result)

输出:

┌────────────┬────────────┬─────────────────────┬────────────┬─────────────────────┐
│ Date       ┆ max_values ┆ max_timestamp       ┆ min_values ┆ min_timestamp       │
│ ---        ┆ ---        ┆ ---                 ┆ ---        ┆ ---                 │
│ date       ┆ i64        ┆ datetime[μs]        ┆ i64        ┆ datetime[μs]        │
╞════════════╪════════════╪═════════════════════╪════════════╪═════════════════════╡
│ 2022-12-02 ┆ 5          ┆ 2022-12-02 09:00:00 ┆ 1          ┆ 2022-12-02 10:00:00 │
│ 2022-10-01 ┆ 2          ┆ 2022-10-01 06:00:00 ┆ 1          ┆ 2022-10-01 04:00:00 │
└────────────┴────────────┴─────────────────────┴────────────┴─────────────────────┘

方法2:使用sort+first/last

如果分组后先按Values排序,再取首尾行也能得到结果,适合需要保留更多列的场景:

max_result_alt = (
    df.sort('Values', descending=True)
    .group_by('Date')
    .first()
    .select('Date', 'Values', 'Timestamps')
    .sort('Date', descending=True)
)
print(max_result_alt)

这个方法会直接取出每组中Values最大的那一行,输出和期望一致。

说明

原代码错误在于pl.max('Values', 'Timestamps')的用法,pl.max只能接收一个列名(或表达式),无法直接关联两个列。需要用arg_max来获取最值对应的行索引,进而提取对应时间戳。

内容的提问来源于stack exchange,提问作者nexty5

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 08:24:56