Pandas如何按固定行数批次对DataFrame行分组聚合?
Pandas 按批次位置分组聚合Duration统计指标实现方案
核心逻辑
扁平化存储的CSV数据按批次连续拼接:第0`batch_size-1`行属于第0轮迭代,`batch_size`2*batch_size-1行属于第1轮迭代,以此类推。结合题设给出的「各批次同位置行的Name值完全一致、单批次内Name可能不唯一」的约束,直接使用行索引对batch_size取模生成位置分组ID即可完成正确分组,完全规避Name字段重复导致的分组错误。
验证样例复现
先构造题中给出的batch_size=3、n_iterations=2简化测试集,其中特意设置单批次内存在重复Name值,贴合真实场景约束:
import pandas as pd import numpy as np # 测试参数 batch_size = 3 n_iterations = 2 # 构造验证输入:两批次同位置Name完全一致,单批次内前两个位置Name均为"A"(存在重复) test_df = pd.DataFrame({ "Name": ["A", "A", "B", "A", "A", "B"], "Duration": [1, 3, 5, 3, 5, 7] })
该测试集按位置分组的正确均值结果为:位置0(第0、3行)均值2,位置1(第1、4行)均值4,位置2(第2、5行)均值6。
三种输出格式实现代码
首先读取正式数据并生成分组辅助列,后续三种格式均基于该预处理结果实现:
# 读取正式数据,替换为你的实际文件路径 df = pd.read_csv("your_data.csv") # 替换为实际参数值 batch_size = 27 n_iterations = 10 # 生成位置分组ID、迭代批次ID df["pos_id"] = df.index % batch_size df["iter_id"] = df.index // batch_size # 可选校验:确认每个位置组内Name完全一致,符合题设前提 # assert (df.groupby("pos_id")["Name"].nunique() == 1).all(), "数据顺序不符合约束"
格式1:拆分各批次Duration为独立列,结果共batch_size行
通过透视表将不同迭代批次的Duration值拆分为Duration_{i}格式的独立列:
out1 = df.pivot(index="pos_id", columns="iter_id", values="Duration") # 补充Name列,同pos_id下Name完全一致,取第一条即可 out1["Name"] = df.groupby("pos_id")["Name"].first() # 重命名列 out1.columns = [f"Duration_{c}" if isinstance(c, int) else c for c in out1.columns] # 调整列顺序,重置索引 out1 = out1[["Name"] + [col for col in out1.columns if col.startswith("Duration_")]].reset_index(drop=True)
在测试集上运行该代码,输出结果与预期完全匹配:
| Name | Duration_0 | Duration_1 |
|---|---|---|
| A | 1 | 3 |
| A | 3 | 5 |
| B | 5 | 7 |
格式2:Duration列存储各批次对应值组成的列表
按位置分组后直接聚合Duration为列表即可:
out2 = df.groupby("pos_id").agg( Name=("Name", "first"), Duration=("Duration", list) ).reset_index(drop=True)
测试集运行结果中,Duration列的值依次为[1, 3]、[3, 5]、[5, 7],符合要求。
格式3:直接输出统计指标列
分组后直接聚合需要的统计量,无需保留单批次原始值:
out3 = df.groupby("pos_id").agg( Name=("Name", "first"), Duration_mean=("Duration", "mean"), Duration_median=("Duration", "median"), Duration_std=("Duration", "std"), Duration_min=("Duration", "min"), Duration_max=("Duration", "max") ).reset_index(drop=True)
测试集运行结果中,Duration_mean列值依次为2、4、6,与验证结果完全一致。
避坑提示
- 禁止直接使用
Name字段作为分组键:题设明确说明单批次内Name可能存在重复,直接按Name分组会错误合并同批次内同名的不同位置数据。 - 该方案依赖「原始CSV按批次连续存储、无乱序」的前提,若数据存在乱序需先按写入顺序排序后再计算。
内容的提问来源于stack exchange,提问作者leosh
相关产品推荐
相关产品推荐

