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

Pandas groupby分组后如何创建布尔列并按条件计算Salary

pandas分组内计算布尔列并完成组内值累加方案

问题复现与错误点说明

现有名为data的DataFrame,需要按['ID','Month']字段拆分分组,所有计算严格限制在组内执行,禁止跨组运算:

  1. 第一步在组内通过行移位计算布尔列B,判断规则为(当前行O值 == 下一行D值) | (当前行D值 == 上一行O值)
  2. 第二步在每个分组内,将B=False行的Salary值,累加到同组所有B=True的行上

示例数据构造代码:

import pandas as pd
data_ = {'ID': [777, 777, 777,777,777,777],'Month':[1,1,1,2,2,2], 'Salary': [130,170,50,140,180,60], 'O': ["ACC","BRU","BRU","ACC","BRU","BRU"], 'D':["LFW","ACC","LFW","LFW","ACC","LFW"]}
data = pd.DataFrame(data=data_)

原有代码的两个核心错误:

  • 孤立调用data.groupby(['ID','Month'])没有赋值给变量,后续shift是直接在全表执行,移位时会跨组取到其他分组的行数据
  • 拆分B=True/B=False子集后直接做加法,没有按分组匹配对应值,会出现索引错位、跨组累加的问题

注意:pandas中单独调用groupby()不会修改原表,也不会让后续的全表操作自动应用分组规则,必须将分组结果赋值给变量,所有组内运算都通过该分组对象调用,才能保证运算不跨组。


正确实现代码

1. 组内计算B列

所有移位操作基于分组对象调用,组边界的行移位后返回空值,不会跨组取数:

# 生成分组对象,后续所有组内运算都基于该对象执行
grp = data.groupby(['ID', 'Month'])
# 组内取上一行O值、下一行D值
prev_O = grp['O'].shift(1)
next_D = grp['D'].shift(-1)
# 计算B列
data['B'] = (data['O'] == next_D) | (data['D'] == prev_O)

2. 组内完成Salary累加

先按组统计B=False行的薪资总和,再将总和分配到同组B=True的行上,以下代码默认将False行薪资平均分配给同组所有True行,如果需要每个True行都加False行的总薪资,去掉代码里除以True行数的逻辑即可:

# 按组统计B=False的薪资总和
false_sal_sum = data.loc[~data['B']].groupby(['ID', 'Month'])['Salary'].sum()
# 按组统计B=True的行数
true_row_cnt = data.loc[data['B']].groupby(['ID', 'Month'])['B'].count()
# 计算每个True行需要累加的薪资值,无True行的组填0避免报错
add_value = (false_sal_sum / true_row_cnt).fillna(0)
# 匹配回原表,非True行累加值填0
data['add_sal'] = data.set_index(['ID','Month']).index.map(add_value.get).fillna(0)
# 仅对B=True的行做薪资累加
data.loc[data['B'], 'Salary'] += data.loc[data['B'], 'add_sal']
# 删除临时列
data = data.drop(columns='add_sal')

结果验证

执行完上述代码后打印data,结果符合预期:每个ID+Month分组共3行,中间行B为True,累加同组首尾两行False的薪资后,1月分组True行薪资为170+130+50=350,2月分组True行薪资为180+140+60=380。
如果数据量较大,上述map匹配方案比循环逐行处理性能高1~2个数量级,适合百万级以上数据集。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:30:50