2016-06-16 23 views
5

Ben DataFrame bir zaman serisi içeren vardır:GroupBy ile TimeGrouper 'geriye'

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

Son giriş 2016-06-07 23:00:00 olduğunu. Şimdi temelde şöyle, bu gruplamaya iki gün demek istiyorum:

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

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

, çok geriye benim son verilerden başlangıç ​​noktası yerine bu sonucu elde gruplandırmak istediğiniz '3D' göre gruplama yaparken

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

ve:

Ben daha ziyade bu beklediğiniz

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

Beklenen sonuç '4D' göre gruplama geçerli:

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

Ben closed her kombinasyonu, label vb düşünebildiğim ile bu almanız mümkün değilim.

Bunu nasıl başarabilirim? Şimdiki soru haftasında gruplaşma odaklanır yana

cevap

0

Ben öncelikle bir hafta aka ben arzu kutularına gelmeye şimdi bu yöntemi kullanıyorum, 7 gün gruba istediğimiz için:

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() 

Bu bana

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

Bu, muhtemelen daha '' 'DateOffset''' ile daha genel olarak yapılabilir. – TomTom101

0

, sadece yapabilirsiniz:

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

Sen işe gitmek için loffset kullanabilirsiniz - en azından (.resample() kullanarak) en dönemler için:

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 

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 
:

Ancak, aynı zamanda şöyle TimeGrouper olmadan doğru değerleri hesaplamak gruplarını oluşturmak olabilir

+0

istenilen çıktıyı verir Teşekkürler! Son kutu benim en önemli olanım olduğundan, çok güvenilir olmak için buna ihtiyacım var. Garip, bunun için yüz-palm kolay çözüm yok gibi görünüyor. – TomTom101

+0

Grup değerlerini güvenilir bir şekilde hesaplamak için ancak TimeGrouper'ı kullanmayan bir çözüm için bkz. – Stefan

+0

Kabul edilmeyi hak ediyor;) Teşekkürler! – TomTom101