【问题标题】:Conditional Running Sum in Pandas for All Previous Values OnlyPandas 中的条件运行总和仅适用于所有以前的值
【发布时间】:2019-09-24 07:16:16
【问题描述】:

假设我有以下 DataFrame:

df = pd.DataFrame({'Event': ['A', 'B', 'A', 'A', 'B', 'C', 'B', 'B', 'A', 'C'], 
                   'Date': ['2019-01-01', '2019-02-01', '2019-03-01', '2019-03-01', '2019-02-15', 
                             '2019-03-15', '2019-04-05', '2019-04-05', '2019-04-15', '2019-06-10'],
                   'Sale': [100, 200, 150, 200, 150, 100, 300, 250, 500, 400]})
df['Date'] = pd.to_datetime(df['Date'])
df

Event         Date  Sale
    A   2019-01-01   100
    B   2019-02-01   200
    A   2019-03-01   150
    A   2019-03-01   200
    B   2019-02-15   150
    C   2019-03-15   100
    B   2019-04-05   300
    B   2019-04-05   250
    A   2019-04-15   500
    C   2019-06-10   400

我想得到以下结果:

Event         Date  Sale   Total_Previous_Sale
    A   2019-01-01   100                     0
    B   2019-02-01   200                     0
    A   2019-03-01   150                   100
    A   2019-03-01   200                   100
    B   2019-02-15   150                   200
    C   2019-03-15   100                     0
    B   2019-04-05   300                   350
    B   2019-04-05   250                   350
    A   2019-04-15   500                   450
    C   2019-06-10   400                   100

其中df['Total_Previous_Sale'] 是事件 (df['Event']) 在其相邻日期 (df['Date']) 之前发生时的总销售额 (df['Sale'])。例如,

  • 事件A发生在2019-01-01之前的总销售量为0,
  • 事件A在2019-03-01之前的总销售量为100,
  • 事件A在2019-04-15之前的总销售量为100 + 150 + 200 = 450。

基本上,它与条件累积和几乎相同,但仅适用于所有先前的值(不包括当前值[s])。我可以使用此行获得所需的结果:

df['Sale_Total'] = [df.loc[(df['Event'] == df.loc[i, 'Event']) & (df['Date'] < df.loc[i, 'Date']), 
                           'Sale'].sum() for i in range(len(df))]

虽然速度很慢,但效果很好。我相信有更好更快的方法来做到这一点。我试过这些行:

df['Total_Previuos_Sale'] = df[df['Date'] < df['Date']].groupby(['Event'])['Sale'].cumsum()

df['Total_Previuos_Sale'] = df.groupby(['Event'])['Sale'].shift(1).cumsum().fillna(0)

但它会产生 NaN 或产生不需要的结果。

【问题讨论】:

    标签: python pandas grouping cumulative-sum


    【解决方案1】:

    首先将sumEventDate 聚合为MultiIndex,然后按第一级Event 分组,并将shift 与lambda 函数的累积和一起使用,最后将join 一起使用:

    s = (df.groupby(['Event', 'Date'])['Sale']
           .sum().groupby(level=0)
           .apply(lambda x: x.shift(1).cumsum())
           .fillna(0)
    
    df = df.join(s.rename('Total_Previuos_Sale'), on=['Event','Date'])
    print (df)
      Event        Date  Sale  Total_Previuos_Sale
    0     A  2019-01-01   100                  0.0
    1     B  2019-02-01   200                  0.0
    2     A  2019-03-01   150                100.0
    3     A  2019-03-01   200                100.0
    4     B  2019-02-15   150                200.0
    5     C  2019-03-15   100                  0.0
    6     B  2019-04-05   300                350.0
    7     B  2019-04-05   250                350.0
    8     A  2019-04-15   500                450.0
    9     C  2019-06-10   400                100.0
    

    【讨论】:

    • 啊,谢谢你的回答。看来您的技术也可以应用于回答this question of mine。请您回答一下好吗?
    【解决方案2】:

    最后,我可以找到一种更好更快的方法来获得想要的结果。事实证明这很容易。可以试试:

    df['Total_Previous_Sale'] = df.groupby('Event')['Sale'].cumsum() \
                              - df.groupby(['Event', 'Date'])['Sale'].cumsum()
    

    【讨论】:

      猜你喜欢
      • 2016-02-19
      • 2012-10-06
      • 2021-11-04
      • 2019-10-29
      • 2017-09-25
      • 1970-01-01
      • 2021-01-17
      • 2019-08-11
      • 1970-01-01
      相关资源
      最近更新 更多