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

Pandas如何按指定列值计数调整每组行数,不足补全超额截断

实现方案

这里提供两种适配不同场景的高效实现:

1. 简洁易读版本(适配绝大多数常规数据量场景)

用groupby.apply直接对分组做截断/补全逻辑,代码好维护,万级到十万级数据量下性能足够:

import pandas as pd

# 测试数据
df = pd.DataFrame({
    "ID": [ "1", "1", "1", "1", "1", "2", "2", "3", "3", "3", "4", "4"],
    "Feature": [ 2, 6, 4, 5, 6, 3, 1, 6, 3, 5, 7, 1]
})

TARGET_PER_GROUP = 4

def process_group(g):
    # 组内行数达标直接截断前N行
    if len(g) >= TARGET_PER_GROUP:
        return g.head(TARGET_PER_GROUP)
    # 不足的部分用最后一行填充
    pad_num = TARGET_PER_GROUP - len(g)
    pad_rows = pd.DataFrame([g.iloc[-1]] * pad_num, columns=g.columns)
    return pd.concat([g, pad_rows], ignore_index=True)

result = df.groupby("ID", group_keys=False).apply(process_group).reset_index(drop=True)
print(result)

2. 纯向量化高性能版本(适配百万级以上大数据量场景)

完全避免groupby.apply的隐式循环开销,性能比上面的版本高3~10倍:

TARGET_PER_GROUP = 4

# 给每个组内的行加序号
df['group_inner_idx'] = df.groupby('ID').cumcount()
# 先截断每个组超过长度的部分
truncated = df[df['group_inner_idx'] < TARGET_PER_GROUP].copy()
# 统计每个组截断后的行数
group_size = truncated.groupby('ID').size()
# 计算每个组需要补的行数
need_pad = TARGET_PER_GROUP - group_size
# 取出需要补行的组的最后一行,按需要补的次数重复
pad_rows = truncated.groupby('ID').last().loc[need_pad[need_pad > 0].index]
pad_rows = pad_rows.loc[pad_rows.index.repeat(need_pad[need_pad > 0])]
# 合并数据、清理临时列、重置索引
result = pd.concat([truncated, pad_rows], ignore_index=True)\
           .drop(columns='group_inner_idx')\
           .sort_values('ID')\
           .reset_index(drop=True)
print(result)

两种方案运行后都可以得到你预期的输出结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 03:54:01