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

Pandas实现条件分组 限制每组antal总和不超过2500的方法

问题结论

这个需求属于带顺序约束的容量限制分组场景,没有可直接套用的pandas内置聚合/分组API实现纯一行流方案,但完全不需要写笨重的逐行DataFrame遍历逻辑,仅需一次轻量线性扫描生成分组标记,再配合pandas原生的groupby聚合就能实现,代码可读性和执行效率都很高。

实现逻辑说明

你的分组规则本质是:按sqm从大到小的顺序依次累加antal,只要累加值不超过2500就归为同一组,超过阈值就开启新组重新累加,组内记录sqm的最大值作为sqm_from、最小值作为sqm_to、antal求和作为组总套数即可。

具体实现代码

首先导入依赖、构造测试数据,注意先按sqm降序排序保证分组顺序正确:

import pandas as pd

# 构造原始数据
df = pd.DataFrame({
    'sqm': [30,29,28,27,26,25,24,23,22,21,20,19,18],
    'antal': [1254,982,1570,1219,1332,1183,1177,679,615,296,369,306,301]
}).sort_values('sqm', ascending=False, ignore_index=True)

# 配置分组阈值
MAX_SUM = 2500

接下来生成分组ID,这里仅遍历antal的数值序列,不操作DataFrame本身,性能极高:

group_col = []
current_total = 0
group_id = 0

for cnt in df['antal']:
    # 加当前值超过阈值就开新组
    if current_total + cnt > MAX_SUM:
        group_id += 1
        current_total = 0
    current_total += cnt
    group_col.append(group_id)

df['gid'] = group_col

最后按分组ID聚合得到结果:

result = df.groupby('gid', as_index=False).agg(
    sqm_from=('sqm', 'max'),
    sqm_to=('sqm', 'min'),
    antal=('antal', 'sum')
).drop(columns='gid')
补充说明

运行代码得到的结果和你给出的期望输出逻辑完全匹配(你给出的示例中24-25分组的antal值2371属于笔误,实际计算值为1183+1177=2360,其余分组结果完全一致)。

不用刻意追求完全不用循环的pandas“纯原生”实现,这类强顺序依赖的分组问题本来就需要一次线性扫描判断边界,只要循环操作的是纯Python数值、不是逐行操作DataFrame的行对象,性能完全可以满足要求,比硬套pandas API写晦涩的奇技淫巧可维护性高很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:27:03