Python Pandas: Mendukung 25 jam dalam indeks datetime

Aug 16 2020

Saya ingin menggunakan tanggal / waktu sebagai indeks untuk kerangka data di Pandas.

Namun, waktu musim panas tidak ditangani dengan benar dalam database, sehingga nilai tanggal / waktu untuk hari di mana waktu musim panas berakhir memiliki 25 jam dan direpresentasikan sebagai berikut:

2019102700
2019102701
...
2019102724

Saya menggunakan kode berikut untuk mengubah nilai-nilai tersebut menjadi DateTimeobjek yang saya gunakan sebagai indeks ke dataframe Pandas:

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

Namun, itu memberikan kesalahan:

ValueError: unconverted data remains: 4

Agaknya karena to_datetimefungsinya tidak mengharapkan jamnya 24. Demikian pula, hari di mana waktu musim panas dimulai hanya memiliki 23 jam.

Satu solusi yang saya pikirkan adalah menyimpan tanggal sebagai string, tetapi tampaknya tidak elegan atau efisien. Apakah ada cara untuk mengatasi masalah penanganan waktu musim panas saat menggunakan to_datetime?

Jawaban

1 MrFuppes Aug 16 2020 at 18:40

Jika Anda tahu zona waktunya, berikut cara menghitung stempel waktu UTC. Parsing hanya bagian tanggal, lokalkan ke zona waktu aktual data "milik", dan konversikan ke UTC. Sekarang Anda dapat mengurai bagian jam dan menambahkannya sebagai delta waktu - mis

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

Saya tidak yakin apakah ini solusi yang paling elegan atau efisien, tetapi saya akan:

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