2012-11-18 19 views
18

Dopo aver combattuto con NumPy e dateutil per giorni, ho scoperto di recente la straordinaria libreria Pandas. Ho esaminato la documentazione e il codice sorgente, ma non riesco a capire come ottenere date_range() per generare indici ai punti di interruzione giusti.Intervalli di date in Pandas

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

quello che voglio:

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

cosa ottengo:

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

Ho bisogno pezzi al mese dimensioni che rappresentano il numero variabile di giorni in un mese. Questo è possibile con dateutil.rrule:

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

Brutto e illeggibile, ma funziona. Come posso fare questo con i Panda? Ho giocato con entrambi date_range() e period_range(), finora senza fortuna.

Il mio obiettivo attuale è quello di utilizzare groupby, crosstab e/o resample per calcolare i valori per ogni periodo sulla base di somme/mezzo/etc di voci individuali all'interno del periodo. In altre parole, voglio trasformare i dati da:

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

a

   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 

Dato che Panda è nato come uno strumento di analisi finanziaria, ne sono praticamente certo che c'è un modo semplice e veloce per fare Questo. Aiuto apprezzato!

risposta

20

freq='M' è per le frequenze di fine mese (vedere here). Ma è possibile utilizzare .shift di spostarlo da un numero qualsiasi di giorni (o di qualsiasi frequenza per questo):

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

Grazie, questo può essere il trucco ho bisogno di creare una soluzione basata su l'hack RRULE. Tuttavia, questo non aiuta il ricampionamento su un intervallo, poiché resample utilizzerà ancora i bin allineati all'inizio del mese AFAIK. – knite

+4

Se avete intenzione di passare da un numero consistente di giorni, è più sensato utilizzare l'inizio mese "MS": 'pd.date_range (start, end, freq = 'MS'). Shift (15, freq = pd. datetools.day) ' –

4

ci realtà c'è un "giorno del mese" di frequenza (ad esempio "DOMXX" come "DOM09"), ma non vedo alcuna ragione per non aggiungerne uno.

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

Non ho una soluzione semplice per voi in questo momento perché resample richiede il superamento di un regola di frequenza nota. Penso che dovrebbe essere aumentato per essere in grado di prendere qualsiasi intervallo di date da utilizzare come bordi di contenitori arbitrari, anche. Solo una questione di tempo e di hacking ...

+1

Questa domanda ha appena raggiunto 10.000 visualizzazioni. Forse è il momento di rivisitare questa funzionalità? – knite

4

provare

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

Per 'freq = ...' si potrebbe usare anche pd.DateOffset (mesi = 1) – calcium3000

Problemi correlati