如何在Pandas DataFrame中实现累积减法计算total_diff列?
实现累计扣除的total_diff列
需求说明
- 每个用户的
total_diff初始值为该用户的总training_hours - 后续每个月,若有
training_hours记录,则用当前total_diff减去该值;若无记录,保持total_diff不变 - 示例:John总时长250,month1-4无记录时
total_diff始终为250;month5记录50小时后,total_diff变为200;month6记录60小时后变为140
原代码问题分析
你之前的代码用cumsum()做累计求和,和需求的累计扣除逻辑完全相反,且空值填充逻辑没有处理好初始总时长的传递,导致结果不符合预期。
正确实现代码
# 1. 提取每个用户的总training_hours,构建映射字典 total_hours_map = df[df['month'].str.endswith('_Total')].set_index('name')['training_hours'].to_dict() # 2. 筛选月度记录行(排除总时长汇总行) mask = ~df['month'].str.endswith('_Total') monthly_records = df[mask].copy() # 3. 为每个用户的月度记录初始化total_diff为总时长 monthly_records['total_diff'] = monthly_records['name'].map(total_hours_map) # 4. 计算累计扣除:总时长减去累计的training_hours(空值按0处理) monthly_records['total_diff'] = monthly_records.groupby('name').apply( lambda group: group['total_diff'].iloc[0] - group['training_hours'].fillna(0).cumsum() ).reset_index(drop=True) # 5. 将处理后的数据合并回原DataFrame df.loc[mask, 'total_diff'] = monthly_records['total_diff'] # 可选:让总时长汇总行的total_diff等于自身training_hours total_mask = df['month'].str.endswith('_Total') df.loc[total_mask, 'total_diff'] = df.loc[total_mask, 'training_hours']
逻辑解释
- 先把每个用户的总时长提取为字典,实现快速匹配
- 为月度记录初始化
total_diff为用户总时长 - 对每个用户的月度时长做累计求和(空值补0),用初始总时长减去该累计值,得到每月剩余时长
- 最后将处理结果合并回原表,总时长行的
total_diff可直接复用自身时长值
内容的提问来源于stack exchange,提问作者Bruce
相关产品推荐
相关产品推荐

