Pandas TimeGrouper:掉落"非完整群组"

时间:2015-03-11 15:49:34

标签: python pandas statistics

我正在以某种频率对我的数据进行分组,但似乎TimeGrouper在右侧创建了一个“剩余”数据的最后一组。

df.groupby([pd.TimeGrouper("2AS", label='left')]).sum()['shopping'].plot()

我希望数据在一段时间内保持相当稳定,但2013的最后一个数据点几乎减少一半。我希望这会发生,因为一年两次的分组,后半部分(2014)缺失。

rolling_mean允许center=True,这会在左右两侧放置NaN / drop余数。石斑鱼有类似的功能吗? I couldn't find any on the manual,但也许有一种解决方法?

left over

1 个答案:

答案 0 :(得分:2)

我不认为这里的问题确实涉及TimeGrouper可用的选项,而是你想如何处理不均衡的数据。你基本上有4个我能想到的选择:

1)删除足够的观察结果(在开始或结束时),以便你有2年的观察倍数。

2)推断您的开始(或结束)期间,使其与具有完整数据的期间相当。

3)根据不到2年的基础时间段将您的数据标准化为2年总和。这种方法可以与其他两种方法结合使用。

4)只需要做一个rolling_sum,而不是groupby方法。


示例数据框:

rng = pd.date_range('1/1/2010', periods=60, freq='1m')
df = pd.DataFrame({ 'shopping' : np.random.choice(12,60) }, index=rng )

我刚从1月1日开始制作带有5年数据的示例数据集,所以如果你每年都这样做,那么你就完成了。

df.groupby([pd.TimeGrouper("AS", label='left')]).sum()['shopping']
Out[206]: 
2010-01-01    78
2011-01-01    60
2012-01-01    76
2013-01-01    51
2014-01-01    60
Freq: AS-JAN, Name: shopping, dtype: int64

这是表格中的问题,前两组基于2年的数据,但第三组仅基于1年的数据。

df.groupby([pd.TimeGrouper("2AS", label='left')]).sum()['shopping']
Out[205]: 
2010-01-01    138
2012-01-01    127
2014-01-01     60
Freq: 2AS-JAN, Name: shopping, dtype: int64

如果你采取上述方法(1),你只需要删除一些观察结果。删除后面的观察并重新输入相同的命令非常容易。放弃之前的观察结果有点棘手,因为那时你的第一次观察并不是在偶数年的1月1日开始,你就失去了自动标记等等。这是一种方法,它将在第一年下降并保留最后4年,但是你会丢失不错的标签(你可以与上面的年度数据进行比较以验证这是正确的):

In [202]: df2 = df[12:]

In [203]: df2['group24'] = (np.arange( len(df2) ) / 24 ).astype(int)

In [204]: df2.groupby('group24').sum()['shopping']
Out[204]: 
group24
0          136
1          111

或者,让我们尝试方法(2),推断。要做到这一点,只需将sum()替换为mean()并乘以24.对于最后一个时期,这意味着我们假设2014年的60将等于2015年的另外60个。无论是否合理的将是你的判断号,你可能想用星号标记并称之为估计。

df.groupby([pd.TimeGrouper("2AS")]).mean()['shopping']*24
Out[208]: 
2010-01-01    138
2012-01-01    127
2014-01-01    120
Freq: 2AS-JAN, Name: shopping, dtype: float64

另外请记住,这只是一种简单(可能是简单化)的方式,你可以在期末推断。这是否是最好的方式(或根本没有意义推断)是根据情况做出的判断要求。

接下来,您可以采用方法(3)并进行某种规范化。我不确定你想要什么,所以我只是勾勒出这些想法。如果你想显示两年的总和,你可以使用前面的替换" 2AS"与" AS"然后乘以2.这基本上使得表格看起来不对,但这将是使图表看起来很好的一种非常简单的方法。

最后,只使用滚动总和:

pd.rolling_sum(df.shopping,window=24)

不能很好地表现出来,但是情节会很好。