Python Pandas: admite 25 horas en el índice de fecha y hora

Aug 16 2020

Quiero usar una fecha / hora como índice para un marco de datos en Pandas.

Sin embargo, el horario de verano no se aborda correctamente en la base de datos, por lo que los valores de fecha / hora para el día en el que finaliza el horario de verano tienen 25 horas y se representan como tales:

2019102700
2019102701
...
2019102724

Estoy usando el siguiente código para convertir esos valores en un DateTimeobjeto que uso como índice para un marco de datos de Pandas:

df.index = pd.to_datetime(df["date_time"], format="%Y%m%d%H")

Sin embargo, eso da un error:

ValueError: unconverted data remains: 4

Presumiblemente porque la to_datetimefunción no espera que sea la hora 24. Del mismo modo, el día en que comienza el horario de verano solo tiene 23 horas.

Una solución en la que pensé fue almacenar las fechas como cadenas, pero eso no parece ni elegante ni eficiente. ¿Hay alguna forma de resolver el problema de manejar el horario de verano cuando se usa to_datetime?

Respuestas

1 MrFuppes Aug 16 2020 at 18:40

Si conoce la zona horaria, aquí hay una forma de calcular las marcas de tiempo UTC. Analice solo la parte de la fecha, localice a la zona horaria real a la que "pertenecen" los datos y conviértalo a UTC. Ahora puede analizar la parte de la hora y agregarla como un delta de tiempo, por ejemplo

import pandas as pd 

df = pd.DataFrame({'date_time_str': ['2019102722','2019102723','2019102724',
                                     '2019102800','2019102801','2019102802']})

df['date_time'] = (pd.to_datetime(df['date_time_str'].str[:-2], format='%Y%m%d')
                   .dt.tz_localize('Europe/Berlin')
                   .dt.tz_convert('UTC'))

df['date_time'] += df['date_time_str'].str[-2:].astype('timedelta64[h]')

# df['date_time']
# 0   2019-10-27 20:00:00+00:00
# 1   2019-10-27 21:00:00+00:00
# 2   2019-10-27 22:00:00+00:00
# 3   2019-10-27 23:00:00+00:00
# 4   2019-10-28 00:00:00+00:00
# 5   2019-10-28 01:00:00+00:00
# Name: date_time, dtype: datetime64[ns, UTC]
1 hoomant Aug 16 2020 at 17:43

No estoy seguro de si es la solución más elegante o eficiente, pero lo haría:

df.loc[df.date_time.str[-2:]=='25', 'date_time'] = (pd.to_numeric(df.date_time[df.date_time.str[-2:]=='25'])+100-24).apply(str)
df.index = pd.to_datetime(df["date_time"], format="%Y%m%d%H")