首页 > 编程问答 >对 groupby 求和并在 groupby 之前添加或子行并在 groupby 之后添加行

对 groupby 求和并在 groupby 之前添加或子行并在 groupby 之后添加行

时间:2024-07-25 13:56:00浏览次数:5  
标签:python dataframe group-by

我有一个数据框,我想获得每个[组]的求和值,其中一行值在该组之前(“减去”和“添加”),在该组之后一行(“BEGUZE_UE”)。 (一个组可以包含不同的字符串,UE_1 并不重要)。 但我在“m_days”中得到了一些错误的结果。感谢您的帮助。

DataFrame:

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) df

使用的代码:

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)] shold 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 shold be 29.67
30           13.00      0.00   1.92  17.95         NaN     NaN

代码中的错误在于,在计算 m_days 时,正在对整个 DataFrame 的 'subtract' 和 'add' 列进行分组和转换,而不仅仅是在计算 tmv 时对相关的行进行分组和转换。

以下是改进后的代码:

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()

# 计算每个组的 'add' 和 'subtract' 的最大值,并计算它们的差值
tmv = (df.groupby(m[::-1].cumsum())[['subtract', 'add']]
       .transform('max')
       .eval('add-subtract')
      )

# 将 'tmv' 与每个组的 'BEGUZ_UE' 的总和相加
df['m_days'] = (df.groupby(m[::-1].cumsum())['BEGUZ_UE']
                .transform('sum')
                .add(tmv['add'] - tmv['subtract'])
                .where(cond)
                .shift()
               )
print(df)

在这个改进后的代码中,我们使用 groupby(m[::-1].cumsum()) tmv 的计算进行了分组,这与我们计算 m_days 时使用的分组相同。这样可以确保 tmv 中的每个值都与 m_days 计算中相应的组对应。

希望这个改进后的代码能够解决遇到的问题!

标签:python,dataframe,group-by
From: 78758299

相关文章