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

Pandas DataFrame按组每N行聚合:解决分组错位的计算问题

按组对每N行数据执行聚合计算的解决方案

问题说明

本需求与“对pandas Series每N行求和”的场景不同,核心是按指定分组字段(如示例中的ID),在每个组内对每N行数据执行聚合计算。但使用全局索引分组时,会因各组行号未对齐导致聚合结果错误,且日期可能完全不规则。

示例数据与预处理代码

import pandas as pd

df = pd.DataFrame({'ID':['AA','AA','AA','BB','BB','BB'], 
                   'DATE':['2021-01-01','2021-01-03','2021-01-08','2021-03-04','2021-03-06','2021-03-08'],
                   'VALUE':[10,15,25,40,60,90]})

df['DATE'] = pd.to_datetime(df['DATE'])
df = df.sort_values(by=['ID','DATE'])

预处理后的DataFrame:

IDDATEVALUE
AA2021-01-0110
AA2021-01-0315
AA2021-01-0825
BB2021-03-0440
BB2021-03-0660
BB2021-03-0890

错误实现及结果

使用全局索引分组的代码:

# 错误的计算方式
df.groupby(['ID', df.index//2]).agg({'VALUE':'mean', 'DATE':'median'}).reset_index()

得到的错误结果:

IDVALUEDATE
AA12.52021-01-02
AA252021-01-08
BB402021-03-04
BB752021-03-07

预期结果

IDVALUEDATE
AA12.52021-01-02
AA252021-01-08
BB502021-03-05
BB902021-03-08

解决方案

问题根源是全局索引df.index//2是对整个DataFrame的索引分组,而非每个ID组内的行号。正确做法是在每个组内生成独立的行号,再基于组内行号进行分组聚合。

方法1:高效生成组内行号(推荐大数据集)

N = 2  # 定义每N行聚合一次
# 生成每个ID组内的连续行号
df['group_row_num'] = df.groupby('ID').cumcount()
# 按ID和组内行号//N分组执行聚合
result = df.groupby(['ID', df['group_row_num']//N]).agg(
    {'VALUE': 'mean', 'DATE': 'median'}
).reset_index(drop=True, level=1).reset_index()

print(result)

方法2:组内独立处理(逻辑直观)

N = 2
def aggregate_n_rows(group):
    # 对单个组按每N行分组聚合
    return group.groupby(group.index//N).agg({'VALUE':'mean', 'DATE':'median'})

result = df.groupby('ID').apply(aggregate_n_rows).reset_index(level=1, drop=True).reset_index()

两种方法均可得到预期结果,其中方法1效率更高;方法2逻辑更直观,适合调试。此外,pandas对datetime类型的median计算天然支持,即使日期完全不规则也能正确输出中间值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:01:25