Groupby with TimeGrouper' backwards'

时间:2016-06-16 17:51:15

标签: python numpy pandas time-series

我有DataFrame包含时间序列:

rng = pd.date_range('2016-06-01', periods=24*7, freq='H')
ones = pd.Series([1]*24*7, rng)
rdf = pd.DataFrame({'a': ones})

最后一项是2016-06-07 23:00:00。我现在想把这个分组,比如两天,基本上是这样的:

rdf.groupby(pd.TimeGrouper('2D')).sum()

但是,我想从最后一个数据点向后分组,所以不要得到这个结果:

            a
2016-06-01  48
2016-06-03  48
2016-06-05  48
2016-06-07  24

我非常期待这一点:

            a
2016-06-01  24
2016-06-03  48
2016-06-05  48
2016-06-07  48

以及按'3D'进行分组:

            a
2016-06-01  24
2016-06-04  72
2016-06-07  72

'4D'分组时的预期结果是:

            a
2016-06-03  72
2016-06-07  96

我无法通过closedlabel等各种组合得到此信息。我能想到的。

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

由于现在的问题主要集中在按周分组,您可以简单地说:

rdf.resample('W-{}'.format(rdf.index[-1].strftime('%a')), closed='right', label='right').sum()

您可以使用loffset让其发挥作用 - 至少在大多数时间段内(使用.resample()):

for i in range(2, 7):
    print(i)
    print(rdf.resample('{}D'.format(i), closed='right', loffset='{}D'.format(i)).sum())

2
             a
2016-06-01  24
2016-06-03  48
2016-06-05  48
2016-06-07  48
3
             a
2016-06-01  24
2016-06-04  72
2016-06-07  72
4
             a
2016-06-01  24
2016-06-05  96
2016-06-09  48
5
              a
2016-06-01   24
2016-06-06  120
2016-06-11   24
6
              a
2016-06-01   24
2016-06-07  144

但是,您也可以创建自定义分组,以便在没有TimeGrouper的情况下计算正确的值,如下所示:

days = rdf.index.to_series().dt.day.unique()[::-1]
for n in range(2, 7):
    chunks = [days[i:i + n] for i in range(0, len(days), n)][::-1]
    grp = pd.Series({k: v for d in [zip(chunk, [idx] * len(chunk)) for idx, chunk in enumerate(chunks)] for k, v in d})
    rdf.groupby(rdf.index.to_series().dt.day.map(grp))['a'].sum()

 2
groups
0    24
1    48
2    48
3    48
Name: a, dtype: int64

 3
groups
0    24
1    72
2    72
Name: a, dtype: int64

 4
groups
0    72
1    96
Name: a, dtype: int64

 5
groups
0     48
1    120
Name: a, dtype: int64

 6
groups
0     24
1    144
Name: a, dtype: int64

答案 1 :(得分:0)

由于我主要想分组7天,也就是一周,我现在使用这种方法来到所需的箱子:

from pandas.tseries.offsets import Week

# Let's not make full weeks
hours = 24*6*4
rng = pd.date_range('2016-06-01', periods=hours, freq='H')

# Set week start to whatever the last weekday of the range is
print("Last day is %s" % rng[-1])
freq = Week(weekday=rng[-1].weekday())

ones = pd.Series([1]*hours, rng)
rdf = pd.DataFrame({'a': ones})
rdf.groupby(pd.TimeGrouper(freq=freq, closed='right', label='right')).sum()

这给了我想要的输出

2016-06-25  96
2016-07-02  168
2016-07-09  168