2012-11-18 39 views
18

Po kilku dniach walki z NumPy i datutilem odkryłem ostatnio niesamowitą bibliotekę Pand. Przeglądałem dokumentację i kod źródłowy, ale nie wiem, jak uzyskać date_range(), aby wygenerować indeksy w odpowiednich punktach przerwania.Zakresy dat w Pandach

from datetime import date 
import pandas as pd 

start = date('2012-01-15') 
end = date('2012-09-20') 
# 'M' is month-end, instead I need same-day-of-month 
date_range(start, end, freq='M') 

Czego chcę:

2012-01-15 
2012-02-15 
2012-03-15 
... 
2012-09-15 

Co dostaję:

2012-01-31 
2012-02-29 
2012-03-31 
... 
2012-08-31 

muszę miesięcznych wielkości kawałki, które konto dla zmiennej liczby dni w miesiącu. Jest to możliwe dzięki dateutil.rrule:

rrule(freq=MONTHLY, dtstart=start, bymonthday=(start.day, -1), bysetpos=1) 

Brzydki i nieczytelny, ale działa. Jak mogę to zrobić z pandami? Grałem zarówno z date_range() i period_range(), jak dotąd bez powodzenia.

Moim rzeczywistym celem jest użycie groupby, crosstab i/lub resample do obliczenia wartości dla każdego okresu w oparciu o sumy/średnie/itp poszczególnych pozycji w okresie. Innymi słowy, chcę, aby przekształcić dane z:

   total 
2012-01-10 00:01 50 
2012-01-15 01:01 55 
2012-03-11 00:01 60 
2012-04-28 00:01 80 

#Hypothetical usage 
dataframe.resample('total', how='sum', freq='M', start='2012-01-09', end='2012-04-15') 

do

   total 
2012-01-09   105 # Values summed 
2012-02-09   0 # Missing from dataframe 
2012-03-09   60 
2012-04-09   0 # Data past end date, not counted 

Zważywszy, że Pandy pochodzi jako narzędzie analizy finansowej, jestem prawie pewien, że jest to prosty i szybki sposób zrobić to. Pomoc doceniona!

Odpowiedz

20

freq='M' jest dla częstotliwości na koniec miesiąca (patrz here). Ale można użyć .shift przesunąć go przez dowolną liczbę dni (lub dowolnej częstotliwości dla tej sprawy):

pd.date_range(start, end, freq='M').shift(15, freq=pd.datetools.day) 
+0

Dzięki, to może być podstęp muszę stworzyć rozwiązanie oparte na hack rrule. Jednak nie pomaga to w ponownym próbkowaniu w zakresie, ponieważ resample nadal będzie korzystać z pojemników wyrównanych do początku miesiąca AFAIK. – knite

+4

Jeśli zamierzasz przesunąć o stałą liczbę dni, lepiej będzie użyć miesiąca start 'MS': 'pd.date_range (start, end, freq = 'MS'). Shift (15, freq = pd. datetools.day) ' –

4

Tam faktycznie ma „dzień miesiąca” częstotliwości (na przykład „DOMXX” jak „DOM09”), ale nie widzę powodu, aby go nie dodawać.

http://github.com/pydata/pandas/issues/2289

nie mam proste obejście dla Ciebie w tej chwili, ponieważ resample wymaga podjęcia znaną regułę częstotliwości. Myślę, że powinno to zostać rozszerzone, aby móc wykorzystać dowolny zakres dat do wykorzystania również jako arbitralne krawędzie skrzyni. To tylko kwestia czasu i włamania ...

+1

To pytanie po prostu wyświetliło 10 tys. wyświetleń. Być może nadszedł czas, aby powrócić do tej funkcji? – knite

4

spróbować

date_range(start, end, freq=pd.tseries.offsets.DateOffset(months=1)) 
+0

Dla "freq = ..." można również użyć pd.DateOffset (miesiące = 1) – calcium3000