我有一个数据框架,其中包含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)
答案 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当然可以解决问题。这是使用stack
和unstack
实现矢量化的另一种方法
(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