【问题标题】:Pandas - Calculate mean for group over expanding window of datesPandas - 在扩展日期窗口中计算组的平均值
【发布时间】:2021-09-26 16:53:53
【问题描述】:

我正在尝试计算按日期分组的扩展窗口平均值。 例如,

df_example = pd.DataFrame({
    'group' : ['a','a','b','b','a','a','b','a','b'],
    'date': ['2021-01-01', '2021-01-01', '2021-01-01', '2021-01-01', '2021-01-02', '2021-01-02','2021-01-02','2021-01-03','2021-01-04'],
    'val' : [True, True, False, True, False, False, True, True,False]
})

  group        date    val
0     a  2021-01-01   True 
1     a  2021-01-01   True 
2     b  2021-01-01  False 
3     b  2021-01-01   True 
4     a  2021-01-02  False 
5     a  2021-01-02  False
6     b  2021-01-02   True
7     a  2021-01-03   True
8     b  2021-01-04  False

为此,我正在寻找的逻辑是:对于每个组和日期,计算小于或等于该日期的所有值的平均值。我已设法按以下方式做到这一点,但正在寻找一种更清洁、更有效的方法来处理它。

df1 = df_example.groupby(['group','date']).sum().groupby('group').cumsum() 
df2 = df_example.groupby(['group','date']).count().groupby('group').cumsum() 
df_result = df1 / df2


                       val
group date                
a     2021-01-01  1.000000
      2021-01-02  0.500000
      2021-01-03  0.600000
b     2021-01-01  0.500000
      2021-01-02  0.666667
      2021-01-04  0.500000

除此之外,我还想扩展数据框,以便在各组中一致地观察每个日期,使用回顾,例如如果没有观察到日期,则使用之前的最新值。

                       val
group date                
a     2021-01-01  1.000000
      2021-01-02  0.500000
      2021-01-03  0.600000
      2021-01-04  0.600000
b     2021-01-01  0.500000
      2021-01-02  0.666667
      2021-01-03  0.666667
      2021-01-04  0.500000

最好以更高效且更易读的方式完成此操作,因为我希望对多个组和值执行类似的逻辑和计算。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    我们可以使用pivot_table

    s = df_example.pivot_table('val', 'group', 'date', ['sum', 'count'])
    s = s['sum'].cumsum(1).div(s['count'].cumsum(1)).ffill(axis=1).stack()
    
    说明
    1. 使用 pivot_table 和 aggfunc sumcount 重塑数据框
          sum                                         count                                 
    date  2021-01-01 2021-01-02 2021-01-03 2021-01-04 2021-01-01 2021-01-02 2021-01-03 2021-01-04
    group                                                                                        
    a            2.0        0.0        1.0        NaN        2.0        2.0        1.0        NaN
    b            1.0        1.0        NaN        0.0        2.0        1.0        NaN        1.0
    
    1. 沿列轴计算sumcount 列的累积和,然后将sum 除以count 以计算扩展均值
    date   2021-01-01  2021-01-02  2021-01-03  2021-01-04
    group                                                
    a             1.0    0.500000         0.6         NaN
    b             0.5    0.666667         NaN         0.5
    
    1. 沿列轴向前填充平均值
    date   2021-01-01  2021-01-02  2021-01-03  2021-01-04
    group                                                
    a             1.0    0.500000    0.600000         0.6
    b             0.5    0.666667    0.666667         0.5
    
    1. 堆叠数据框以重塑为多索引系列
    group  date      
    a      2021-01-01    1.000000
           2021-01-02    0.500000
           2021-01-03    0.600000
           2021-01-04    0.600000
    b      2021-01-01    0.500000
           2021-01-02    0.666667
           2021-01-03    0.666667
           2021-01-04    0.500000
    dtype: float64
    

    【讨论】:

    • 这个答案完美无缺,并且在我的实际数据集上表现出色。为其他可能阅读的人明确分解步骤:(1) s = pd.pivot_table(data = df_example., values='val', index = 'group', columns='date',aggfunc = ['sum' ,'count'] 将形成一个数据透视表,给出日期扩展。对于跨多个列的分组值可以用列表替换 (2) 第二行计算每个数据透视表列的累积总和。这给出扩展窗口的想法,因为 s 数据框中的列是日期。(3) ffill 替换任何缺失值
    • @user157545 感谢您分解这些步骤。我还用所有中间步骤的解释编辑了答案。
    猜你喜欢
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 2014-12-09
    • 2023-01-19
    • 2016-06-06
    • 2018-08-26
    相关资源
    最近更新 更多