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

Pandas如何按指定列分组且每组固定n行 可从原DataFrame删除分组数据

问题场景

你持有一个规模为数千行的pandas DataFrame,样例数据结构如下:

a   b   c
x   2   3
y   2   3
z   3   2
w   1   5
# 共数千条记录

最初你直接使用b、c列作为分组键遍历:

for x,y in df.groupby(['b','c']):
    print(y)

该方式会将相同b、c值的所有记录归为同一组,无法满足拆分要求。以n=1(单组最多1行)为例,默认分组结果如下:

a   b   c
x   2   3
y   2   3

a   b   c
z   3   2

a   b   c
w   1   5

你期望的效果是同一b、c组合下超过n行的部分自动拆分为新分组,n=1时期望输出为:

a   b   c
x   2   3

a   b   c
y   2   3

a   b   c
z   3   2

a   b   c
w   1   5

同时需要支持将已提取的分组数据从原始DataFrame中删除。

实现方案

核心思路是在b、c基础分组之上,给组内每条记录计算子分组编号:使用组内累计序号对n做整除取整,将子分组编号与b、c共同作为分组键,即可自动完成超量记录的拆分,全程使用pandas内置向量化方法,性能远高于逐行遍历。

完整拆分代码

import pandas as pd

# 1. 初始化示例数据(替换为你自己的DataFrame即可)
df = pd.DataFrame({
    'a': ['x', 'y', 'z', 'w'],
    'b': [2, 2, 3, 1],
    'c': [3, 3, 2, 5]
})

n = 1  # 自定义每个分组的最大行数
# 2. 给每个b、c组内的记录生成子分组ID
df['sub_group_id'] = df.groupby(['b', 'c']).cumcount() // n
# 3. 按复合键分组,得到所有符合行数要求的分组
groups = [g.drop(columns=['sub_group_id']) for _, g in df.groupby(['b', 'c', 'sub_group_id'])]

# 遍历验证分组结果
for g in groups:
    print(g, '\n')

运行后输出与你期望的n=1拆分结果完全一致。调整n的数值即可灵活控制单组最大行数,例如n=2时,同一b、c下每2行会被归为一个独立分组。

提取分组后删除原表对应数据

不要在循环中逐行执行drop操作(性能极低),直接通过布尔索引筛选即可快速完成提取和原表裁剪:

# 示例:提取每个b、c组合下的第一组(前n行数据)
extracted_data = df[df['sub_group_id'] == 0].drop(columns=['sub_group_id'])
# 原表仅保留未被提取的剩余数据
df = df[df['sub_group_id'] != 0].drop(columns=['sub_group_id'])

如果需要按顺序逐批提取分组,每处理完一批分组,只需要通过行索引匹配筛选剩余数据即可,全流程无冗余遍历,处理十万级以上数据也能保持很高的运行效率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 05:27:47