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

Pandas分组求和及前后行计算异常:m_days字段结果错误求助

问题排查与修正:Pandas分组计算m_days字段错误

需求说明

对每个由非空ATEXT构成的连续分组,计算以下值的总和:

  • 分组内所有BEGUZ_UE的求和
  • 分组前一行的add - subtract值
  • 分组后一行的BEGUZ_UE值

UE_1字段不影响计算。

原始DataFrame

import pandas as pd

data = {'ATEXT': ['', 'CT', 'RT', '', '', '', '', 'CT', 'CT', 'CT', 'RT', '', '', '', 'CTS', 'CT',
              '', 'CT', 'RT', 'RT', 'RT', 'CT', '', 'CT', 'RT', 'RT', '', '', 'CT', '', ''], 
    'BEGUZ_UE': [11.00, 23.00, 33.00, 15.00, 12.75, 19.75, 14.75, 23.00, 24.00, 24.00, 33.00, 15.00, 14.25, 13.00,
                 23.00, 24.00, 11.00, 23.00, 33.00, 24.00, 24.00, 24.00, 6.00, 23.00, 33.00, 24.00, 10.68,
                 21.00, 23.00, 12.75, 13.00],
    'subtract': [00.00, 00.00, 00.00, 00.00, 00.00, 3.57, 00.00, 00.00, 00.00, 00.00, 00.00, 00.08, 00.00, 00.00,
                 00.00, 00.00, 00.00, 00.00, 00.00, 00.00, 00.00, 00.00, 00.00, 00.00, 00.00, 00.00, 00.00,
                 6.08, 00.00, 00.00, 00.00], 
    'add': [3.92, 00.00, 00.00, 00.00, 4.95, 00.00, 2.95, 00.00, 00.00, 00.00, 00.00, 00.00, 2.62, 1.92, 00.00, 
            00.00, 3.92, 00.00, 00.00, 00.00, 00.00, 00.00, 12.00, 00.00, 00.00, 00.00, 2.95, 00.00, 00.00, 4.95,
            1.92],
    'UE_1': ['', '', '', '', 12.67, 24.7, 11.18, '', '', '', '', '', 14.17, 15.62, '', '',
             '', '', '', '', '', '', '', '', '', '', '', 23.95, '', '', 17.95]}
df = pd.DataFrame(data)

用户原始代码

m = df['ATEXT'].eq("")
cond = (~m) & m.shift(-1)
df['UE_more_days'] = (df['BEGUZ_UE'].mask(m)
                      .groupby(m.cumsum()).cumsum()
                      .where(cond)
                     ).shift() # orginal ohne shift() hier
tmv = (df[['subtract', 'add']]
       .shift()
       .groupby(m.cumsum())
       .transform('max')
       .eval('add-subtract')
      )
df['m_days'] = (df.groupby(m[::-1].cumsum())['BEGUZ_UE']
                .transform('sum')
                .add(tmv)
                .where(cond)
                .shift()
               )

错误结果(标注问题项)

ATEXT  BEGUZ_UE  subtract    add   UE_1  UE_more_days  m_days
0            11.00     0.00    3.92               NaN     NaN
1     CT    23.00     0.00     0.00                NaN     NaN
2     RT    33.00     0.00     0.00                NaN     NaN
3           15.00     0.00     0.00             56.0    74.92  ok
4            12.75     0.00     4.95  12.67         NaN     NaN
5            19.75     3.57     0.00   24.7         NaN     NaN
6            14.75     0.00     2.95  11.18         NaN     NaN
7     CT    23.00     0.00     0.00                NaN     NaN
8     CT    24.00     0.00     0.00                NaN     NaN
9     CT    24.00     0.00     0.00                NaN     NaN
10    RT    33.00     0.00     0.00                NaN     NaN
11          15.00     0.08     0.00            104.0   118.38  should be 121.95
12           14.25     0.00     2.62  14.17         NaN     NaN
13           13.00     0.00     1.92  15.62         NaN     NaN
14   CTS     23.00     0.00     0.00                NaN     NaN
15    CT     24.00     0.00     0.00                NaN     NaN
16           11.00     0.00     3.92               47.0    60.62  should be 59.92
17    CT     23.00     0.00     0.00                NaN     NaN
18    RT     33.00     0.00     0.00                NaN     NaN
19    RT     24.00     0.00     0.00                NaN     NaN
20    RT     24.00     0.00     0.00                NaN     NaN
21    CT     24.00     0.00     0.00                NaN     NaN
22            6.00     0.00    12.00              128.0   137.92  ok
23    CT     23.00     0.00     0.00                NaN     NaN
24    RT     33.00     0.00     0.00                NaN     NaN
25    RT     24.00     0.00     0.00                NaN     NaN
26           10.68     0.00     2.95               80.0   102.68  ok
27           21.00     6.08     0.00  23.95         NaN     NaN
28    CT     23.00     0.00     0.00                NaN     NaN
29           12.75     0.00     4.95               23.0    32.62  should be 29.67
30           13.00     0.00     1.92  17.95         NaN     NaN

问题分析

  1. 分组标识错误:原代码用m[::-1].cumsum()反向生成分组ID,导致分组范围与非空ATEXT的连续区间不匹配,计算的BEGUZ_UE求和错误。
  2. 前一行值提取错误:tmv部分用groupby(m.cumsum()).transform('max')取分组内的最大值,而需求是取每个非空分组前一行的add-subtract,逻辑完全错误。
  3. 未纳入分组后一行的BEGUZ_UE:原代码完全遗漏了需求中“分组后一行的BEGUZ_UE”这一项。

修正代码

import pandas as pd

# 1. 标记非空ATEXT的连续分组
df['non_empty'] = df['ATEXT'].ne('')
df['group_id'] = df['non_empty'].cumsum()
valid_groups = df[df['non_empty']]['group_id'].unique()

# 2. 计算每个分组的BEGUZ_UE求和
group_sum = df.groupby('group_id')['BEGUZ_UE'].sum().rename('group_sum')

# 3. 获取每个分组前一行的add - subtract
group_start = df[df['non_empty']].groupby('group_id').head(1).index
prev_row_vals = df.loc[group_start - 1, ['add', 'subtract']].eval('add - subtract').rename('prev_val')

# 4. 获取每个分组后一行的BEGUZ_UE
group_end = df[df['non_empty']].groupby('group_id').tail(1).index
next_row_vals = df.loc[group_end + 1, 'BEGUZ_UE'].rename('next_val')

# 5. 合并所有计算值,得到每个分组的m_days
group_calc = pd.concat([group_sum, prev_row_vals, next_row_vals], axis=1)
group_calc['m_days'] = group_calc['group_sum'] + group_calc['prev_val'] + group_calc['next_val']

# 6. 将m_days映射回原DataFrame的对应位置(分组后的第一空行)
df['m_days'] = None
for gid in valid_groups:
    after_group_idx = df[(df['group_id'] == gid) & df['non_empty']].index[-1] + 1
    if after_group_idx < len(df):
        df.loc[after_group_idx, 'm_days'] = group_calc.loc[gid, 'm_days']

# 修正UE_more_days(原逻辑基本正确,调整分组标识)
df['UE_more_days'] = df['BEGUZ_UE'].mask(df['non_empty'] == False).groupby(df['group_id']).cumsum()
df['UE_more_days'] = df['UE_more_days'].where(df['non_empty'] & df['non_empty'].shift(-1).fillna(False)).shift()

# 清理临时列
df.drop(['non_empty', 'group_id'], axis=1, inplace=True)

# 输出结果(保留两位小数)
print(df[['ATEXT', 'BEGUZ_UE', 'UE_more_days', 'm_days']].round(2))

修正后关键结果验证

  • 第11行m_days:104 + 2.95 + 15 = 121.95(符合预期)
  • 第16行m_days:47 + 1.92 + 11 = 59.92(符合预期)
  • 第29行m_days:23 + (-6.08) + 12.75 = 29.67(符合预期)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:42:03