【问题标题】:Pandas, how to calculate mean values of the past n years for every month熊猫,如何计算每个月过去n年的平均值
【发布时间】:2020-05-18 01:58:54
【问题描述】:

我有一个数据框,其中包含 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 年。这意味着前 3 年我将获得 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)

【问题讨论】:

  • 能不能先把原始数据贴出来再求和?

标签: python pandas time-series


【解决方案1】:

我猜不出您的数据框中的列和索引是什么。所以假设它是:

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

【讨论】:

  • 哦,哇,是的,这就是我要找的。但是你能解释一下代码吗?为什么在聚合中还需要添加当年的最大值?为什么需要“reset_index”或第二个“groupby()”?
【解决方案2】:

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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    相关资源
    最近更新 更多