2015-02-27 1 views
18

Ho un pandas.DataFrame chiamato df, che ha un indice generato automaticamente, con una colonna dt:Tronca `TimeStamp` colonna per la precisione ora in panda` DataFrame`

df['dt'].dtype, df['dt'][0] 
# (dtype('<M8[ns]'), Timestamp('2014-10-01 10:02:45')) 

Quello che mi piacerebbe fare è creare una nuova colonna troncata a precisione oraria. Attualmente sto usando:

df['dt2'] = df['dt'].apply(lambda L: datetime(L.year, L.month, L.day, L.hour)) 

Questo funziona, quindi va bene. Tuttavia, ho un indizio c'è un modo carino usando pandas.tseries.offsets o creando un DatetimeIndex o simile.

Quindi, se possibile, c'è qualche procedura guidata pandas per fare questo?

+0

Così si vuole gli stessi valori, ma senza secondi corretta – EdChum

+0

@EdChum senza minuti o secondi ... sono interessati solo a un'ora di precisione –

risposta

26

In pandi 0.18.0 e successive, ci sono datetime floor, ceil e round metodi per arrotondare timestamp a una data precisione/frequenza fissa. Per arrotondare verso il basso per la precisione ora, è possibile utilizzare:

>>> df['dt2'] = df['dt'].dt.floor('h') 
>>> df 
         dt      dt2 
0 2014-10-01 10:02:45  2014-10-01 10:00:00 
1 2014-10-01 13:08:17  2014-10-01 13:00:00 
2 2014-10-01 17:39:24  2014-10-01 17:00:00 

Ecco un'altra alternativa per troncare i timestamp. A differenza di floor, supporta il troncamento a una precisione come anno o mese.

È possibile regolare temporaneamente l'unità precisione del sottostante NumPy datetime64 tipo di dati, cambiandolo [ns]-[h]:

df['dt'].values.astype('<M8[h]') 

Questo tronca tutto per la precisione ora. Per esempio:

>>> df 
         dt 
0  2014-10-01 10:02:45 
1  2014-10-01 13:08:17 
2  2014-10-01 17:39:24 

>>> df['dt2'] = df['dt'].values.astype('<M8[h]') 
>>> df 
         dt      dt2 
0 2014-10-01 10:02:45  2014-10-01 10:00:00 
1 2014-10-01 13:08:17  2014-10-01 13:00:00 
2 2014-10-01 17:39:24  2014-10-01 17:00:00 

>>> df.dtypes 
dt  datetime64[ns] 
dt2 datetime64[ns] 

Lo stesso metodo dovrebbe funzionare per qualsiasi altra unità: mesi 'M', minuti 'm', e così via:

  • Tieniti anno: '<M8[Y]'
  • Tieniti mese: '<M8[M]'
  • Tieniti giorno: '<M8[D]'
  • Tieniti minuto: '<M8[m]'
  • Tieniti secondo: '<M8[s]'
+2

Grande risposta. Waaay più veloce di 'datetime.replace', che è la soluzione più comune menzionata su SO. –

1

Un metodo che ho usato in passato per raggiungere questo obiettivo è stato il seguente (del tutto simile a quello che si sta già facendo, ma ho pensato di buttare fuori c'è comunque):

df['dt2'] = df['dt'].apply(lambda x: x.replace(minute=0, second=0)) 
Problemi correlati