2013-04-23 16 views
43

Io uso pandas.to_datetime per analizzare le date nei miei dati. Pandas per impostazione predefinita rappresenta le date con datetime64[ns] anche se le date sono tutte solo giornaliere. Mi chiedo se esiste un modo elegante/intelligente per convertire le date in datetime.date o datetime64[D] in modo che, quando scrivo i dati su CSV, le date non vengano aggiunte con 00:00:00. So che posso convertire il tipo di elemento per elemento manualmente:Mantieni solo la parte della data quando si utilizza pandas.to_datetime

[dt.to_datetime().date() for dt in df.dates] 

Ma questo è molto lento dal momento che ho molte righe ed è sorta di sconfitte lo scopo di utilizzare pandas.to_datetime. C'è un modo per convertire lo dtype dell'intera colonna in una sola volta? Oppure, in alternativa, lo standard pandas.to_datetime supporta una specifica di precisione in modo che sia possibile eliminare la parte temporale mentre si lavora con i dati giornalieri?

+0

non so un buon modo, ma 'df.dates.apply (lambda x: x.date())' dovrebbe essere almeno un po 'più veloce. dare un'occhiata a https://github.com/pydata/pandas/issues/2583 – root

+0

possibile duplicato di [Come specificare il formato della data quando si utilizza pandas.to \ _csv?] (http://stackoverflow.com/questions/ 13999850/how-to-specific-date-format-when-using-pandas-to-csv) – unutbu

+1

Considererei queste due domande come diverse. Il possibile duplicato a cui si fa riferimento mira a suddividere la parte di data e ora da una colonna datetime. Questa domanda è motivata convertendo l'intera colonna in una sola volta. Immagina di avere un dataframe con 20 colonne che rappresentano le date. Non vorresti specificare quali colonne scrivere in csv, come suggerito nell'altra domanda. – ezbentley

risposta

1

Conversione datetime64[D]:

df.dates.values.astype('M8[D]') 

Sebbene riassegna che ad un colle dataframe si tornerà di nuovo [ns].

Se si voleva effettivamente datetime.date:

dt = pd.DatetimeIndex(df.dates) 
dates = np.array([datetime.date(*date_tuple) for date_tuple in zip(dt.year, dt.month, dt.day)]) 
+2

Se si utilizza astype ('M8 [D]') trasforma i valori mancanti nella data di origine, 1970-1-1. Probabilmente è meglio usare solo pandas.to_datetime() al giorno d'oggi. –

70

Dalla versione 0.15.0 questo può ora essere fatto facilmente utilizzando .dt per accedere solo il componente di data:

df['just_date'] = df['dates'].dt.date 
+4

Sfortunatamente '' df ['just_date'] '' ha quindi '' object'' dtype (e quindi, per esempio, non c'è un '' .dt'' accessor) ... un modo per evitarlo? –

+2

@PietroBattiston che significa che probabilmente è ancora una stringa, prova a convertire prima 'df ['just_date'] = pd.to_datetime (df ['just_date'])' potresti dover passare un 'format' arg a' to_datetime' se non è possibile dedurre il formato – EdChum

+0

In realtà è un '' datetime.date'' ... ma detto questo, il riesecuzione di '' pd.to_datetime'' su di esso sembra funzionare perfettamente, grazie! –

8

Pandas DatetimeIndex e Series hanno un metodo chiamato normalize che fa esattamente quello che vuoi.

Ulteriori informazioni a riguardo sono disponibili in this answer.

che sarà scritto come ser.dt.normalize()

6

Mentre io upvoted risposta di EdChum, che è la risposta più diretta alla domanda del PO pone, in realtà non risolve il problema di prestazioni (si basa ancora su Python datetime oggetti, e quindi qualsiasi operazione su di essi non sarà vettorizzata, cioè sarà lenta).

A better performing alternative utilizza df['dates'].dt.floor('d'). A rigor di termini, non "mantiene solo una data", poiché imposta semplicemente l'ora su 00:00:00. Ma funziona, se lo desideri dal PO quando, per esempio:

  • stampa allo schermo
  • risparmio di csv
  • utilizzando la colonna di groupby

... ed è molto più efficiente, dal momento che l'operazione è vettorializzata.

EDIT: infatti, la risposta del PO del avrebbero preferito è probabilmente "le versioni recenti di pandas fanno non scrivere il tempo di csv se è 00:00:00 per tutte le osservazioni".

+0

Sfortunatamente 'to_json' scrive ancora il pieno' 00: 00: 00'. – IanS

+0

@IanS intendi quando usi '' date_format = 'iso''' ?! Di default, emette solo pochi secondi dall'epoca. –

+0

Sì, questo è quello che intendevo. – IanS

-2

viene utilizzato per la data di stampa

import pandas as pd d='2015-01-08 22:44:09' c= pd.to_datetime(d).date() print c

Problemi correlati