【问题标题】:How to perform rolling sum from another category如何从另一个类别执行滚动求和
【发布时间】:2020-05-09 16:25:35
【问题描述】:


我正在尝试执行一些计算以检索另一个类别的两次出现之间的类别的滚动总数。
我意识到用语言来描述并不容易。
所以,这里是输入数据帧和预期输出的例子

输入:

Date       Category  Value
2012-01-04        A     10
2012-01-06        A     20
2012-02-15        B    -10
2012-04-29        A      5
2012-04-30        A     70
2012-10-15        A     15
2012-10-16        B    -30
2012-11-19        B    -50

预期输出: 只有 B 行,但提到了自上次 B 出现以来 A 的滚动总数

Date       Category  Value  Total_A_since_previous_B
2012-02-15        B    -10                        30
2012-10-16        B    -30                        90
2012-11-19        B    -50                         0

我已经尝试了几件事,但都没有成功。
你能帮我理解怎么做吗?

【问题讨论】:

  • 你尝试过的几件事是什么?他们有什么问题?

标签: python pandas rolling-computation


【解决方案1】:

首先为 B 的每次出现创建组,对值求和,然后将其作为新列分配给过滤后的 df。

(
    pd.Series(np.where(df.Category.eq('B'), df.index, np.nan)).bfill()
    .pipe(lambda x: df.groupby(x).Value.apply(lambda x: x[:-1].sum()))
    .pipe(lambda x: df[df.Category=='B'].assign(Total_A_since_previous_B=x))
)

    Date        Category    Value   Total_A_since_previous_B
2   2012-02-15  B           -10     30
6   2012-10-16  B           -30     90
7   2012-11-19  B           -50     0

【讨论】:

  • 不是那么简单,所以我将详细了解更多信息:) 还有一个问题,如何包含第一列 Product 来对每个产品的结果进行分组?跨度>
  • 哦,对不起,它也可以。!!!所以没问题。再次非常感谢。
【解决方案2】:

使用GroupBy.agg:

blocks = df.Category.shift().eq('B').cumsum()
new_df = (df.groupby(blocks)
            .agg(Date= ('Date','last'),
                 Category = ('Category','last'),
                 Value = ('Value','last'),
                 Total_A_since_previous_B = ('Value','sum')
                )
             .assign(Total_A_since_previous_B = lambda x: x.Total_A_since_previous_B
                                                           .sub(x.Value))
             .reset_index(drop=True))

print(new_df)
         Date Category  Value  Total_A_since_previous_B
0  2012-02-15        B    -10                        30
1  2012-10-16        B    -30                        90
2  2012-11-19        B    -50                         0

【讨论】:

  • 您的解决方案生成 4 行而不是 3 行。
  • 现在检查@MykolaZotko
  • 也感谢您的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
相关资源
最近更新 更多