熊猫5yr& 10年均线

时间:2017-04-04 19:10:51

标签: pandas moving-average

我有一个数据框,其中我的索引是datetime dtype但日期不是任何顺序排序。我希望计算我的数据集的5年和10年移动平均值。通过使用.rolling_mean我可以根据我设置窗口的内容取平均值,但是,因为日期不是连续的,所以这不起作用。

Dataframe:
    Date          Count
    1981-01-08    10
    1981-05-12    65
    1982-03-17    96
    1982-09-15    33
    1982-12-01    85
    1983-02-03    14
    .
    .
    . 
    2017-01-28    56

Code: 
counts_df = pd.DataFrame(df.groupby('DATE').size().rename('counts'))
start_date_periods = counts_df.loc[counts_df.index > '1981-01-01']
start_date_periods['5yrMA'] = pd.rolling_mean(start_date_periods, window=5)
start_date_periods['10yrMA'] = pd.rolling_mean(start_date_periods, window=10)

3 个答案:

答案 0 :(得分:3)

这是滚动功能的一种情况,就像宣传的那样工作,但没有做你想做的事情。在最新版本的Pandas中,您应该在使用rolling_mean时收到警告,因为它已被弃用而不是rolling所以为了说明我将使用rolling:< / p>

滚动功能旨在处理任何数据,而不仅仅是时间序列。所以它回顾过去&#39; x个单位。使用window参数设置回顾。它根据数据帧的排序顺序进行回顾。因此,即使您正确地对数据进行排序,rolling也不知道您的意思是多年,当您给它一个5的窗口时......它只能看到&#34;回顾5个单元格&#34; < / p>

因此,如果您想要回顾5年来缺少值的数据,您需要用某些东西填充这些值。您可以使用NaN,也可以使用Pandas提供的众多插值方法之一。我将说明NaN方法:

由于您没有提供一些易于使用的合成数据,我设置了一些:

np.random.seed(1)
ts_data = pd.DataFrame(np.random.randn(6210),
                       index = pd.date_range('2000-01-01', '2016-12-31', freq='D'), 
                       columns=['data']) # index of every day for 7 years

ts_sample = ts_data.sample(n=10).sort_index() ## sample then sort
print ts_sample

返回一个包含10个值和日期索引的精心排序的示例df:

               data
2001-07-21  0.107343
2003-07-12  0.658537
2004-08-21 -0.463338
2006-07-13 -0.866955
2011-12-14  0.020956
2012-05-14 -2.685125
2012-12-27  0.494037
2013-06-09 -1.299026
2013-12-12  0.371309
2015-06-17  0.201656

所以为了填补这些缺失的值,让我们创建一个新的df,只包含一整天的完整索引:

full_period = pd.DataFrame(index = pd.date_range('2000-01-01', '2016-12-31', freq='D') )

由于Pandas如何使用索引,如果您将示例数据弹出到列中,Pandas将使用NaN填充缺失值:

full_period['data'] = ts_sample.data
print full_period['2015-06-16':'2015-06-18']

我只打印三天,所以我们可以看到它如何弹出数据:

                data
2015-06-16       NaN
2015-06-17  0.201656
2015-06-18       NaN

现在我们有一整套日常数据,缺少数据NaN。现在我们可以做滚动的意思:

rolling = full_period.rolling(min_periods=1, window=365*5,center=False).mean() # daily data so using 5 years of days
print rolling['2015-06-16':'2015-06-18']

再次打印相同的3个值:

                data
2015-06-16 -0.619570
2015-06-17 -0.482699
2015-06-18 -0.482699

如果您只想选择仅返回原始日期的滚动平均值,则可以使用一个小的衬垫来执行此操作:

print rolling.ix[ts_sample.index.tolist()]

                data
2001-07-21  0.107343
2003-07-12  0.382940
2004-08-21  0.100847
2006-07-13 -0.141103
2011-12-14  0.020956
2012-05-14 -1.332085
2012-12-27 -0.723377
2013-06-09 -0.867290
2013-12-12 -0.619570
2015-06-17 -0.482699

答案 1 :(得分:0)

在计算滚动数据之前,将数据帧与索引进行排序。

答案 2 :(得分:0)

使用pandas当前的rolling函数,可以直接传递天数的窗口大小:rolling('365d')为1年,rolling('1826d')为5年,闰年考虑了额外的天数(不完全准确,但涵盖了大多数情况),rolling('3652d') 10 年。将仅计算滚动窗口中观察到的数据点的平均值。