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

Pandas 如何提取分组内累计值占比达X%的前N行数据

Pandas 分组按价值占比筛选最少记录实现方案

核心逻辑

利用分组累积求和计算价值占比,筛选出刚好达到覆盖阈值的最少行,不需要额外排序(原数据已按分组内Value降序排列)。

代码实现

可读性优先版本(推荐,性能更好)

import pandas as pd

# 自定义覆盖阈值,示例为覆盖90%的分组总价值
COVERAGE_THRESHOLD = 0.9

# 计算每个分组的总价值
df['group_total'] = df.groupby('Group')['Value'].transform('sum')
# 计算分组内逐行累积价值
df['cum_value'] = df.groupby('Group')['Value'].cumsum()
# 计算累积价值占分组总价值的比例
df['cum_ratio'] = df['cum_value'] / df['group_total']

# 筛选满足阈值的行,额外保留刚好超过阈值的第一行(避免分组首行占比就超阈值时无返回的边界问题)
filtered_df = df[
    df['cum_ratio'].le(COVERAGE_THRESHOLD) 
    | df.groupby('Group')['cum_ratio'].transform('idxmin').eq(df.index)
]

# 可选:删除中间计算列
filtered_df = filtered_df.drop(columns=['group_total', 'cum_value', 'cum_ratio'])

# 查看结果
# 1. 总符合要求的记录数
print(f"总最少记录数:{len(filtered_df)}")
# 2. 每个分组对应的最少记录数
print(filtered_df.groupby('Group').size())

精简版本

import pandas as pd
COVERAGE_THRESHOLD = 0.9

filtered_df = df[
    df.groupby('Group')['Value'].apply(
        lambda x: (x.cumsum()/x.sum()).le(COVERAGE_THRESHOLD) 
        | (x.cumsum()/x.sum()).idxmin() == x.index
    )
]

注意事项

  • 仅适用于分组内已经按Value列降序排序的数据集,若未排序需要先执行df = df.sort_values(['Group', 'Value'], ascending=[True, False])
  • 内置的边界处理逻辑会保证每个分组至少返回1条记录,不会出现分组筛选结果为空的情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:39:04