Come faccio a convertire le date in un frame di dati Pandas in un tipo di dati "date"?


104

Ho un frame di dati Panda, una delle colonne contiene stringhe di data nel formato YYYY-MM-DD

Per es '2013-10-28'

Al momento il dtypedella colonna è object.

Come si convertono i valori delle colonne nel formato di data Panda?

Risposte:


109

Usa astype

In [31]: df
Out[31]: 
   a        time
0  1  2013-01-01
1  2  2013-01-02
2  3  2013-01-03

In [32]: df['time'] = df['time'].astype('datetime64[ns]')

In [33]: df
Out[33]: 
   a                time
0  1 2013-01-01 00:00:00
1  2 2013-01-02 00:00:00
2  3 2013-01-03 00:00:00

1
Bello - grazie - come faccio a sbarazzarmi delle 00:00:00 alla fine di ogni appuntamento?
user7289

1
Il timestamp dei panda ha sia la data che l'ora. Intendi convertirlo in un oggetto data python?
waitkuo

7
Puoi convertirlodf['time'] = [time.date() for time in df['time']]
aspettando

3
cosa significa il [ns], puoi rendere la stringa di testo una data e rimuovere la parte temporale di quella data?
yoshiserry

1
@yoshiserry sono nanosecondi, ed è il modo in cui le date vengono memorizzate sotto il cofano una volta convertite correttamente (tempo-epoca in nanosecondi).
Andy Hayden

113

Essenzialmente equivalente a @waitingkuo, ma lo userei to_datetimequi (sembra un po 'più pulito e offre alcune funzionalità aggiuntive, ad esempio dayfirst):

In [11]: df
Out[11]:
   a        time
0  1  2013-01-01
1  2  2013-01-02
2  3  2013-01-03

In [12]: pd.to_datetime(df['time'])
Out[12]:
0   2013-01-01 00:00:00
1   2013-01-02 00:00:00
2   2013-01-03 00:00:00
Name: time, dtype: datetime64[ns]

In [13]: df['time'] = pd.to_datetime(df['time'])

In [14]: df
Out[14]:
   a                time
0  1 2013-01-01 00:00:00
1  2 2013-01-02 00:00:00
2  3 2013-01-03 00:00:00

Gestione ValueErrors
Se ti imbatti in una situazione in cui stai facendo

df['time'] = pd.to_datetime(df['time'])

Lancia un

ValueError: Unknown string format

Ciò significa che hai valori non validi (non coercibili). Se ti va di convertirli in pd.NaT, puoi aggiungere un errors='coerce'argomento a to_datetime:

df['time'] = pd.to_datetime(df['time'], errors='coerce')

Ciao ragazzi, @AndyHayden potete rimuovere la parte dell'ora dalla data? Non mi serve quella parte?
yoshiserry

Nella 0.13.1 dei panda gli 00: 00: 00 finali non vengono visualizzati.
Andy Hayden

e per quanto riguarda le altre versioni, come le rimuoviamo / e o non le mostriamo?
yoshiserry

Non penso che questo possa essere fatto in un modo carino, c'è una discussione per aggiungere date_format come float_format (che hai visto). Consiglio comunque l'aggiornamento.
Andy Hayden

il mio problema è che la mia data è in questo formato ... 41516.43 e ottengo questo errore. Mi aspetto che restituisca qualcosa come 2014-02-03 nella nuova colonna ?! L'ERRORE: #converte i valori della data nella colonna "load_date" in date budget_dataset ['date_last_load'] = pd.to_datetime (budget_dataset ['load_date']) budget_dataset -c: 2: SettingWithCopyAvvertenza: si sta tentando di impostare un valore su un copia di una sezione da un DataFrame. Prova a utilizzare .loc [row_index, col_indexer] = value invece
yoshiserry

35

Immagino che molti dati entrino in Panda da file CSV, nel qual caso puoi semplicemente convertire la data durante la lettura CSV iniziale:

dfcsv = pd.read_csv('xyz.csv', parse_dates=[0])dove lo 0 si riferisce alla colonna in cui si trova la data.
Puoi anche aggiungere , index_col=0lì se vuoi che la data sia il tuo indice.

Vedi https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html


Grazie, era esattamente quello di cui avevo bisogno. La documentazione è stata spostata, tuttavia, puoi trovarla qui: pandas.pydata.org/pandas-docs/stable/reference/api/…
Sastibe

24

Adesso puoi farlo df['column'].dt.date

Nota che per gli oggetti datetime, se non vedi l'ora in cui sono tutti 00:00:00, non è panda. Questo è il notebook iPython che cerca di far sembrare le cose belle.


2
Questo non funziona per me, si lamenta: può usare solo l'accessor
.dt

2
potrebbe essere necessario df[col] = pd.to_datetime(df[col])prima convertire la colonna in oggetti di data e ora.
szeitlin

Il problema con questa risposta è che converte la colonna in dtype = objectcui occupa molta più memoria rispetto a un vero datetime dtypein Panda.
elPastor

6

Un altro modo per farlo e funziona bene se hai più colonne da convertire in datetime.

cols = ['date1','date2']
df[cols] = df[cols].apply(pd.to_datetime)

Domanda chiedi data non datetime.
Mark Andersen

@MarkAndersen fintanto che hai datesolo valori nelle colonne, la conversione a datetime manterrà solo le informazioni pertinenti. Se si converte esplicitamente usando, si df['datetime_col'].dt.dateotterrà un objectdtype; perdita nella gestione della memoria.
Sumanth Lazarus il


1

Potrebbe essere necessario convertire le date in una frequenza diversa. In questo caso, suggerirei di impostare un indice per date.

#set an index by dates
df.set_index(['time'], drop=True, inplace=True)

Dopo questo, puoi convertire più facilmente nel tipo di formato della data di cui avrai più bisogno. Di seguito, converto in sequenza in un numero di formati di data, finendo infine con una serie di date giornaliere all'inizio del mese.

#Convert to daily dates
df.index = pd.DatetimeIndex(data=df.index)

#Convert to monthly dates
df.index = df.index.to_period(freq='M')

#Convert to strings
df.index = df.index.strftime('%Y-%m')

#Convert to daily dates
df.index = pd.DatetimeIndex(data=df.index)

Per brevità, non mostro di eseguire il seguente codice dopo ogni riga sopra:

print(df.index)
print(df.index.dtype)
print(type(df.index))

Questo mi dà il seguente output:

Index(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='object', name='time')
object
<class 'pandas.core.indexes.base.Index'>

DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='datetime64[ns]', name='time', freq=None)
datetime64[ns]
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>

PeriodIndex(['2013-01', '2013-01', '2013-01'], dtype='period[M]', name='time', freq='M')
period[M]
<class 'pandas.core.indexes.period.PeriodIndex'>

Index(['2013-01', '2013-01', '2013-01'], dtype='object')
object
<class 'pandas.core.indexes.base.Index'>

DatetimeIndex(['2013-01-01', '2013-01-01', '2013-01-01'], dtype='datetime64[ns]', freq=None)
datetime64[ns]
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>

0

Prova a convertire una delle righe in timestamp usando la funzione pd.to_datetime e poi usa .map per mappare il formular all'intera colonna


0
 #   Column          Non-Null Count   Dtype         
---  ------          --------------   -----         
 0   startDay        110526 non-null  object
 1   endDay          110526 non-null  object

import pandas as pd

df['startDay'] = pd.to_datetime(df.startDay)

df['endDay'] = pd.to_datetime(df.endDay)

 #   Column          Non-Null Count   Dtype         
---  ------          --------------   -----         
 0   startDay        110526 non-null  datetime64[ns]
 1   endDay          110526 non-null  datetime64[ns]

0

Per completezza un'altra opzione, che potrebbe non essere la più semplice, un po 'simile a quella proposta da @SSS, ma utilizzando piuttosto la libreria datetime è:

import datetime
df["Date"] = df["Date"].apply(lambda x: datetime.datetime.strptime(x, '%Y-%d-%m').date())
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.