熊猫,如何计算每个月过去n年的平均值

时间:2020-05-16 13:25:10

标签: python pandas time-series

我有一个数据框架,其中包含20年的数据,时间作为数据时间索引。

编辑

Time value
1999-01-01 00:00:00 7 1999-01-01 01:00:00 4 1999-01-01 02:00:00 9 1999-01-01 03:00:00 4 1999-01-01 04:00:00 2 ... 2018-12-31 19:00:00 8 2018-12-31 20:00:00 1 2018-12-31 21:00:00 9 2018-12-31 22:00:00 6 2018-12-31 23:00:00 5

我需要得到每个月的总和,

df_new = df.groupby([df.index.year, df.index.month]).sum()

结果

     Month  value
1999    1   6
        2   9
        3   7
2000    1   5
        2   7
        3   6
2001    1   4
        2   6
        3   8
2002    1   7
        2   9
        3   8
2003    1   5
        2   7
        3   7
        ....
2018    1   9
        2   6
        3   7

但是现在我需要一种方法来计算过去3年每个月的平均值。例如对于2002年,我将具有:对于第1个月,1999,2000,2001的第1个月的平均值,对于第2个月,1999,2000,2001的第2个月的平均值,依此类推。然后,2003年的平均值将是2000、2001和2002的平均值,直到2018年为止。这意味着前三年我将获得Nan值。

所以我的最终输出应如下所示:

   Month    value   average_past_3_years
1999    1   6   nan
        2   9   nan
        3   7   nan
2000    1   5   nan
        2   7   nan
        3   6   nan
2001    1   4   nan
        2   6   nan
        3   8   nan
2002    1   7   5.0
        2   9   7.3
        3   8   7.0
2003    1   5   5.3
        2   7   7.3
        3   7   7.3
            ...

我当时在考虑使用.apply(),但无法找出使它起作用的功能:(

df.groupby([df.index.year, df.index.month]).apply(somefunction)

2 个答案:

答案 0 :(得分:0)

我无法猜测数据框中的列和索引是什么。因此,假设它是:

df = pd.DataFrame({'year': [1999.0, 1999.0, 1999.0, 2000.0, 2000.0, 2000.0,
                            2001.0, 2001.0, 2001.0, 2002.0, 2002.0, 2002.0,
                            2003.0, 2003.0, 2003.0],
                   'Month': ['1', '2', '3', '1', '2', '3', '1', '2', '3',
                             '1', '2', '3', '1', '2', '3'],
                   'value': ['6', '9', '7', '5', '7', '6', '4', '6', '8',
                             '7', '9', '8', '5', '7', '7']})

给予:

0   year Month value
1   1999     1     6
2   1999     2     9
3   1999     3     7
4   2000     1     5
5   2000     2     7
6   2000     3     6
7   2001     1     4
8   2001     2     6
9   2001     3     8
10  2002     1     7
11  2002     2     9
12  2002     3     8
13  2003     1     5
14  2003     2     7
15  2003     3     7

您可以按月分组,并使用大小为3的滚动窗口来计算每月最近3年的滚动总和,并移动结果以使其对齐:

df['average_past_3_years'] = df.groupby('Month').rolling(3).agg(
                      {'value':'mean', 'year': 'max'}).reset_index(level=0).groupby(
                      'Month').transform('shift')['value']

它将按预期提供:

0   year Month value  average_past_3_years
1   1999     1     6                   NaN
2   1999     2     9                   NaN
3   1999     3     7                   NaN
4   2000     1     5                   NaN
5   2000     2     7                   NaN
6   2000     3     6                   NaN
7   2001     1     4                   NaN
8   2001     2     6                   NaN
9   2001     3     8                   NaN
10  2002     1     7              5.000000
11  2002     2     9              7.333333
12  2002     3     8              7.000000
13  2003     1     5              5.333333
14  2003     2     7              7.333333
15  2003     3     7              7.333333

答案 1 :(得分:0)

Groupby当然可以解决问题。这是使用stackunstack实现矢量化的另一种方法

(df.set_index(['Year', 'Month'])['value'] # set up indexed-series
   .unstack('Month')                        # reshape into matrix
   .rolling(3)                 # rolling mean, across all months
   .mean() 
   .stack(dropna=False))      # Reshape back