¿Cómo convierto fechas en un marco de datos de Pandas a un tipo de datos de 'fecha'?


104

Tengo un marco de datos de Pandas, una de las columnas contiene cadenas de fecha en el formato YYYY-MM-DD

Por ejemplo '2013-10-28'

Por el momento el dtypede la columna es object.

¿Cómo convierto los valores de la columna al formato de fecha Pandas?

Respuestas:


109

Usar un tipo

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
Bien, gracias, ¿cómo me deshago de las 00:00:00 al final de cada cita?
user7289

1
La marca de tiempo de los pandas tiene fecha y hora. ¿Quiere decir convertirlo en un objeto de fecha de Python?
esperandokuo

7
Puede convertirlo pordf['time'] = [time.date() for time in df['time']]
esperandokuo

3
¿Qué significa [ns], puede convertir la cadena de texto en una fecha y eliminar la parte de la hora de esa fecha?
yoshiserry

1
@yoshiserry son nanosegundos, y es la forma en que las fechas se almacenan bajo el capó una vez convertidas correctamente (época-tiempo en nanosegundos).
Andy Hayden

113

Esencialmente equivalente a @waitingkuo, pero lo usaría to_datetimeaquí (parece un poco más limpio y ofrece alguna funcionalidad adicional, por ejemplo 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

Manejo ValueErrors
Si se encuentra en una situación en la que

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

Lanza un

ValueError: Unknown string format

Eso significa que tiene valores inválidos (no coercibles). Si está de acuerdo con convertirlos a pd.NaT, puede agregar un errors='coerce'argumento a to_datetime:

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

Hola chicos, @AndyHayden, ¿pueden eliminar la parte de tiempo de la fecha? ¿No necesito esa parte?
yoshiserry

En pandas '0.13.1 no se muestran las 00: 00: 00s finales.
Andy Hayden

y en otras versiones, ¿cómo las eliminamos o no las mostramos?
yoshiserry

No creo que esto se pueda hacer de una manera agradable, hay una discusión para agregar date_format como float_format (que has visto). Recomiendo actualizar de todos modos.
Andy Hayden

mi problema es que mi fecha está en este formato ... 41516.43, y aparece este error. ¿Esperaría que devolviera algo como 2014-02-03 en la nueva columna? EL ERROR: #convertir valores de fecha en la columna "load_date" a fechas budget_dataset ['date_last_load'] = pd.to_datetime (budget_dataset ['load_date']) budget_dataset -c: 2: SettingWithCopy Advertencia: Se está intentando establecer un valor en un copia de un segmento de un DataFrame. Intente usar .loc [row_index, col_indexer] = value en su lugar
yoshiserry

35

Me imagino que muchos datos ingresan a Pandas desde archivos CSV, en cuyo caso simplemente puede convertir la fecha durante la lectura CSV inicial:

dfcsv = pd.read_csv('xyz.csv', parse_dates=[0])donde el 0 se refiere a la columna en la que está la fecha.
También puede agregar , index_col=0allí si desea que la fecha sea su índice.

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


Gracias, eso era exactamente lo que necesitaba. Sin embargo, la documentación se ha movido, puede encontrarla aquí: pandas.pydata.org/pandas-docs/stable/reference/api/…
Sastibe

24

Ahora puedes hacer df['column'].dt.date

Tenga en cuenta que para los objetos de fecha y hora, si no ve la hora en la que todos son 00:00:00, eso no es pandas. Ese es el portátil iPython que intenta que las cosas se vean bonitas.


2
Este no funciona para mí, se queja: solo se puede usar el acceso .dt con valores de fecha y hora
smishra

2
es posible que tenga que hacer df[col] = pd.to_datetime(df[col])primero para convertir su columna en objetos de fecha y hora.
szeitlin

El problema con esta respuesta es que convierte la columna en la dtype = objectque ocupa considerablemente más memoria que una verdadera datetime dtypeen pandas.
elPastor

6

Otra forma de hacer esto y esto funciona bien si tiene varias columnas para convertir a fecha y hora.

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

Pregunta pide fecha, no fecha y hora.
Mark Andersen

@MarkAndersen siempre que datesolo tenga valores en sus columnas, la conversión a fecha y hora solo retendrá la información pertinente. Si convierte explícitamente el uso df['datetime_col'].dt.date, resultará en un objectdtype; Pérdida en la gestión de la memoria.
Sumanth Lazarus


1

Puede darse el caso de que las fechas deban convertirse a una frecuencia diferente. En este caso, sugeriría establecer un índice por fechas.

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

Después de esto, puede convertir más fácilmente al tipo de formato de fecha que más necesite. A continuación, convierto secuencialmente a varios formatos de fecha, y finalmente termino con un conjunto de fechas diarias al comienzo del mes.

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

Por brevedad, no muestro que ejecuto el siguiente código después de cada línea anterior:

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

Esto me da el siguiente resultado:

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

Intente convertir una de las filas en una marca de tiempo usando la función pd.to_datetime y luego use .map para asignar el formulario a toda la columna


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

En aras de la integridad, otra opción, que podría no ser la más sencilla, un poco similar a la propuesta por @SSS, pero usando más bien la biblioteca de fecha y hora es:

import datetime
df["Date"] = df["Date"].apply(lambda x: datetime.datetime.strptime(x, '%Y-%d-%m').date())
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.