2015-06-09 8 views
6

Attualmente sto generando un DateTimeIndex utilizzando una determinata funzione, zipline.utils.tradingcalendar.get_trading_days. Le serie temporali sono approssimativamente giornaliere ma con alcune lacune.Ottenere l'ultimo giorno di ogni mese di una serie storica pands

Il mio obiettivo è quello di ottenere l'ultimo appuntamento nello DateTimeIndex per ogni mese.

.to_period('M') & .to_timestamp('M') non funzionano poiché danno l'ultimo giorno del mese anziché l'ultimo valore della variabile in ogni mese.

Ad esempio, se questa è la mia serie temporale, desidero selezionare "2015-05-29" mentre l'ultimo giorno del mese è "2015-05-31".

['2015-05-18', '2015-05-19', '2015-05-20', '2015-05-21', '2015-05-22', '2015-05 -26 ',' 2015-05-27 ',' 2015-05-28 ', ' 2015-05-29 ',' 2015-06-01 ']

+4

Spiacente non sarà 'df.groupby ([df.index.year, df. index.month]). last() 'dai quello che vuoi? – EdChum

+0

No, purtroppo non. Dai un'occhiata al mio post per un esempio. – ikemblem

+0

Non sono sicuro del motivo per cui il commento di Ed non funzionerà. Il tuo post prima si converte in un periodo, mentre il commento di Ed esamina solo l'ultimo giorno di trading in un dato mese per ogni anno. – Alexander

risposta

2

La risposta di Condla si avvicinava di più a ciò di cui avevo bisogno, tranne che dal momento che il mio indice temporale si estendeva per oltre un anno, avevo bisogno di raggruppare per mese e anno e quindi selezionare la data massima. Di seguito è riportato il codice con cui ho finito.

# tempTradeDays is the initial DatetimeIndex 
dateRange = [] 
tempYear = None 
dictYears = tempTradeDays.groupby(tempTradeDays.year) 
for yr in dictYears.keys(): 
    tempYear = pd.DatetimeIndex(dictYears[yr]).groupby(pd.DatetimeIndex(dictYears[yr]).month) 
    for m in tempYear.keys(): 
     dateRange.append(max(tempYear[m])) 
dateRange = pd.DatetimeIndex(dateRange).order() 
+0

Mi piace.Ma forse esiste una soluzione interna ai panda per questo oggi ... – Pat

3

La mia strategia sarebbe raggruppare per mese e quindi selezionare il "massimo" di ogni gruppo:

Se "dt" è il vostro oggetto DatetimeIndex:

last_dates_of_the_month = [] 
dt_month_group_dict = dt.groupby(dt.month) 
for month in dt_month_group_dict: 
    last_date = max(dt_month_group_dict[month]) 
    last_dates_of_the_month.append(last_date) 

la lista "last_date_of_the_month" contiene tutte le date che si verificano ultime di ogni mese nella vostra dat un set. È possibile utilizzare questo elenco per creare nuovamente un DatetimeIndex nei panda (o qualsiasi altra cosa si voglia fare).

1

Forse non è necessario la risposta più, ma durante la ricerca di una risposta alla stessa domanda ho trovato forse una soluzione più semplice:

import pandas as pd 

sample_dates = pd.date_range(start='2010-01-01', periods=100, freq='B') 
month_end_dates = sample_dates[sample_dates.is_month_end] 
+0

OP indica chiaramente "se questa è la mia serie temporale, vorrei selezionare '2015-05-29' mentre l'ultimo giorno del mese è '2015-05- 31' ." La tua soluzione mancherebbe il 2015-05-29 poiché non è un mese. –

1

Questa è una vecchia questione, ma tutti esistenti risposte qui non sono perfetti Questa è la soluzione mi è venuta (assumendo che la data è un indice ordinato), che può essere anche scritto in una sola riga, ma ho diviso per la leggibilità:

month1 = pd.Series(apple.index.month) 
month2 = pd.Series(apple.index.month).shift(-1) 
mask = (month1 != month2) 
apple[mask.values].head(10) 

alcune note qui:

  • Spostando una serie datetime richiede un'altra pd.Series esempio (vedi here)
  • booleana maschera indicizzazione richiede .values (vedi here)

Tra l'altro, quando sono le date dei giorni, sarebbe più facile da usare ricampionamento: apple.resample('BM')

Problemi correlati