【问题标题】:How to calculate average weekly spend with groupby, with week being Monday to Sunday?如何使用groupby计算平均每周支出,每周是周一到周日?
【发布时间】:2019-12-19 23:21:32
【问题描述】:

我有一个包含购买金额和日期的客户数据框。在这种情况下,我有两个客户,AB

df1 = pd.DataFrame(index=pd.date_range('2015-04-24', periods = 50)).assign(purchase=[x for x in range(51,101)])
df2 = pd.DataFrame(index=pd.date_range('2015-04-28', periods = 50)).assign(purchase=[x for x in range(0,50)])

df3 = pd.concat([df1,df2], keys=['A','B'])

df3 = df3.rename_axis(['user','date']).reset_index()
print(df3.head())

  user       date  purchase
0    A 2015-04-24        51
1    A 2015-04-25        52
2    A 2015-04-26        53
3    A 2015-04-27        54
4    A 2015-04-28        55

我只想知道用户的平均每周支出,一周是从周一到周日。预期结果:

  user       average_weekly_spend 
0    A       51
1    B       60

但是我不知道如何将其设置为星期一到星期日。现在我使用resample7D。我认为,这意味着所有客户都会对一周有不同的定义。我相信从第一次购买等到需要 7 天。所以每个客户都会有不同的开始日期。

df3.groupby('user').apply(lambda x: x.resample('7D', on='date').mean()).groupby('user')['purchase'].mean()


user
A    78.125
B    27.125

是否可以为所有客户将我自己的一周定义为周一至周日?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    看来你需要W-Mon频率:

    df = (df3.groupby('user')
             .resample('W-Mon', on='date')['purchase']
             .mean()
             .mean(level=0)
             .reset_index())
    print (df)
      user  purchase
    0    A      75.5
    1    B      28.7
    

    不确定这里是否有好的解决方案使用means 中的mean,也许您可​​以通过重新采样获得计数和总和,然后根据定义创建均值 - 总和除以计数:

    df = (df3.groupby('user')
             .resample('W-Mon', on='date')['purchase']
             .agg(['size','sum'])
             .sum(level=0))
    df['mean'] = df.pop('sum') / df.pop('size')
    print (df)
          mean
    user      
    A     75.5
    B     24.5
    

    【讨论】:

    • 这里每个人的答案都有不同的答案值!
    • @SCool 我猜是因为手段的意思。
    【解决方案2】:

    有趣的是,to_period 的另一个解决方案给出了不同的答案:

    df3.groupby(['user',df3.date.dt.to_period('W-MON')]).mean().mean(level='user')
    

    输出:

          purchase
    user          
    A       75.500
    B       27.125
    

    【讨论】:

    • 这里的所有三个答案都给出了不同的值。嗯!
    【解决方案3】:

    在 Python 中,日期范围已被索引为周一至周日。

    如果你只是使用 pandas.Series.dt.week 方法来获取周数,这很容易。

    df3['week_number'] = df3['date'].dt.week
    df3.head(20)
    

    您可以查看上面的 df3,第 18 周从 2015 年 4 月 27 日开始,即星期一。

    df4 = df3.groupby(['user','week_number']).mean()
    
    # Final mean
    df4.groupby(['user']).mean()
    

    我认为这是正确的平均每周支出。但是,这与您在帖子中作为预期结果分享的内容不同。

    Output:
    
    user    purchase
    A   74.625
    B   26.250
    

    【讨论】:

    • 有趣的是这里的三个答案都有不同的值。
    • @SCool:不过只能是一个正确答案:) 在将原始数据帧减少到 30 个条目(句点 = 15)之后,我手动检查了数学,并且在我的代码中它加起来了。所以其他答案不可能是正确的。能否请您也检查一下,然后选择一个答案?
    • 我上班后会检查并回复你
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 2017-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多