如何在Pandas DataFrame中仅调整总和超标的分组最大值
解决分组总和超限时仅调整最大值的问题
我来帮你修正这个问题~你的核心思路是对的:找到每个分组的最大值并调整它,把分组总和降到100以内,但原代码的问题在于没有过滤掉总和≤100的分组,导致这些分组的最大值反而被加上了负数(相当于增加数值),完全不符合需求。
修正后的代码(循环版,直观易懂)
import pandas as pd # 初始化数据集 df = pd.DataFrame([ ['A', 60], ['A', 20], ['A', 21], ['B', 35], ['B', 33], ['B', 32], ['C', 40], ['C', 40], ['C', 10], ], columns=['Item', 'Count']) # 1. 计算每个Item分组的总和 group_sums = df.groupby('Item')['Count'].sum() # 2. 计算每个分组需要减去的超出值(总和≤100的话,超出值为0) overages = group_sums.apply(lambda x: max(0, x - 100)) # 3. 找到每个分组中Count最大值的索引 max_indices = df.groupby('Item')['Count'].idxmax() # 4. 仅对有超出值的分组,调整其最大值 for item, idx in max_indices.items(): if overages[item] > 0: df.loc[idx, 'Count'] -= overages[item] print(df)
输出结果
Item Count 0 A 59 1 A 20 2 A 21 3 B 35 4 B 33 5 B 32 6 C 40 7 C 40 8 C 10
代码解释
- 步骤1:先算出每个Item的总和,方便后续判断是否需要调整。
- 步骤2:用
max(0, x-100)确保只有总和超过100的分组才会有正的超出值,其余分组的调整量为0,不会改动数据。 - 步骤3:找到每个分组中Count最大的那条数据的索引,这是我们要调整的目标。
- 步骤4:遍历每个分组,只对有超出值的分组,从其最大值中减去对应的超出量,完美实现需求。
进阶:向量化版本(适合大数据集)
如果你的数据集很大,循环效率较低,可以用更简洁的向量化方式实现,避免循环:
import pandas as pd df = pd.DataFrame([ ['A', 60], ['A', 20], ['A', 21], ['B', 35], ['B', 33], ['B', 32], ['C', 40], ['C', 40], ['C', 10], ], columns=['Item', 'Count']) # 计算每个分组的总和和超出值 df['group_sum'] = df.groupby('Item')['Count'].transform('sum') df['overage'] = df['group_sum'].apply(lambda x: max(0, x - 100)) # 标记当前行是否是分组内的最大值 df['is_max'] = df.groupby('Item')['Count'].transform(lambda x: x == x.max()) # 仅对是最大值且有超出值的行调整Count df.loc[df['is_max'] & (df['overage'] > 0), 'Count'] -= df['overage'] # 清理临时列 df = df.drop(['group_sum', 'overage', 'is_max'], axis=1) print(df)
这个版本效率更高,最终效果和循环版完全一致。
内容的提问来源于stack exchange,提问作者Yubraj Bhusal
相关产品推荐
相关产品推荐

