【问题标题】:DataFrame: cumulative sum of column until condition is reached and return sum in new columnDataFrame:列的累积总和,直到达到条件并在新列中返回总和
【发布时间】:2020-04-08 09:13:11
【问题描述】:

我是 Python 新手,目前面临一个我无法解决的问题。我真的希望你能帮助我。英语不是我的母语,所以如果我不能正确表达自己,我很抱歉。

假设我有一个像这样的数据框:

import pandas as pd
df = pd.DataFrame({'a': [1111,2222,3333,4444,5555,6666,7777,8888,9999], 'b':[0,0,1,0,1,0,0,0,1]})

我需要对“a”中的数据求和,直到达到“b中有值”的条件。 这意味着对于给定的数据框:

At index=2 there is a 1 in b --> sum rows 0+1+2 = 6666
At index=4 there is a 1 in b --> sum rows 3+4 = 9999
At index=8 there is a 1 in b --> sum rows 5+6+7+8 = 33330

我尝试了 if else 情况,但没有令人满意的输出..

问候

【问题讨论】:

    标签: python pandas dataframe sum


    【解决方案1】:

    使用Series.shiftSeries.cumsum 的累积和然后聚合sum

    df = df.groupby(df.b.shift(fill_value=0).cumsum())['a'].sum().rename_axis(None).to_frame()
    print (df)
           a
    0   6666
    1   9999
    2  33330
    

    对于新列,首先使用GroupBy.transformsum,然后在b numpy.where 中设置0 如果不匹配1

    s = df.groupby(df.b.shift(fill_value=0).cumsum())['a'].transform('sum')
    df['cumsum'] = np.where(df.b == 1, s, 0)
    
    print (df)
          a  b  cumsum
    0  1111  0       0
    1  2222  0       0
    2  3333  1    6666
    3  4444  0       0
    4  5555  1    9999
    5  6666  0       0
    6  7777  0       0
    7  8888  0       0
    8  9999  1   33330
    

    【讨论】:

    • 哦,太好了!感谢您的快速答复!工作正常!如何更改您的代码以创建一个新列,让我们说“cumsum”在 1 位于 b 中的位置填充 6666、9999、33330,并且原始数据框看起来相同。
    • 好吧,我很抱歉我在 cmets 中换行太愚蠢了……希望现在可以理解了。原始DataFrame可以通过新列“cumsum”扩展,其中6666999933330位于1在b列的同一行? a b0 1111 01 2222 02 3333 13 4444 04 5555 15 6666 06 7777 07 8888 08 9999 1
    • 是的,看到并改变了它;)对于未来的观众:两种解决方案都有效
    • 是否还有一个命令来获取累计列的平均值?对于上述情况:(1111+2222+3333)/3(4444+5555)/2?
    • @Klamsi - 将 sum 更改为 mean 函数。
    【解决方案2】:

    运行:

    df.a.groupby(df.b[::-1].cumsum()).sum()\
        .sort_index(ascending=False).reset_index(drop=True).to_frame()
    

    注意分组是按照b倒序进行的,所以看 在此列按“前进”顺序,1 的每个值终止 当前组。

    “后处理”步骤涉及:

    • 颠倒顺序(按索引),
    • 重置索引,
    • 转换为 DataFrame(如果需要)。

    【讨论】:

      猜你喜欢
      • 2017-05-20
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      • 1970-01-01
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      相关资源
      最近更新 更多