如何在 Pandas 中处理夏令时 DST 而不会出现 AmbiguousTime 或 NonExistantTime 错误

How to handle Daylight savings time DST in Pandas without getting AmbiguousTime or NonExistantTime Errors

我处理必须处理夏令时 (DST) 的大型数据集。 这是我在 Whosebug 上间接找到的解决方案。我试图更直接地回答这个问题,以便其他人可以更快地找到它。

问题和设置。 基本上,如何将 pandas 中的日期时间列转换为特定时区或 UTC。如果没有带 DST 的日期时间,这很容易。但是对于 DST,则必须执行一些额外的步骤。

数据集:

2012-03-24 23:00;    4.9741
2012-03-25 00:00;    4.9443
2012-03-25 01:00;    4.9443
2012-03-25 02:00;    4.9160
2012-03-25 03:00;    4.8865
2012-03-25 04:00;    4.8865
2012-03-25 05:00;    4.8584
2012-10-27 22:00;    2.1982
2012-10-27 23:00;    2.1982
2012-10-28 00:00;    2.1982
2012-10-28 01:00;    2.1839
2012-10-28 02:00;    2.1839
2012-10-28 03:00;    2.1982
2012-10-28 04:00;    2.1839
2012-10-28 05:00;    2.1839

现在有 spring 和秋季 DST 的数据 数据以 csv 形式出现,并已加载和准备:

import pandas 

df = pandas.read_csv('data_file_path', sep=';', encoding='utf-8')
def column_names(df):
    df.columns=['Time', 'Value']
    return df

df = column_names(df)

def change_str_column_to_float(df):
    df['Value'] = pandas.to_numeric(df['Value'])
    return df

df = change_str_column_to_float(df)

数据现已清理和准备。现在介绍如何将时间转换为 UTC 时间或特定时区。

数据来自挪威,但接收时未应用挪威时区。我想应用挪威时区,并在必要时将其转换为 UTC 所以有两种可能的解决方案。两者都是:

import pytz

def add_norwegian_timezone(df):
    timeZone = pytz.timezone("Europe/Oslo")
    df['Time'] = df['Time'].dt.tz_localize('UTC')
    df['Time'] = df['Time'].dt.tz_convert(timeZone)
    return df

def convert_to_utc(df):
    timeZone = pytz.timezone("Europe/Oslo")
    df['Time'] = df['Time'].dt.tz_localize('UTC')
    df['Time'] = df['Time'].dt.tz_convert(timeZone)
    df['Time'] = df['Time'].dt.tz_convert('UTC')
    return df

我发现有趣的是,当 pandas 日期时间列中没有定义时区时,您必须首先应用 UTC 时区 (df['Time'] = df['Time'].dt.tz_localize('UTC')).之后,您应用该数据集的实际时区 (df['Time'] = df['Time'].dt.tz_convert(timeZone))。然后您的数据在当地时区,在本例中为挪威语。如果您随后希望数据采用 UTC 格式,则将其转换回 UTC (df['Time'] = df['Time'].dt.tz_convert('UTC'))。

您必须执行这些步骤很奇怪,但我发现这是让 pandas 考虑 DST 而不会出现 AmbiguousTime 或 NonExistantTime 错误的唯一方法。

我很确定这是正确的,当我 运行 它时,日期时间被正确转换并且没有发现错误。但我希望得到反馈,以确保我向社区分享了正确的信息,并且没有遗漏任何信息。

谢谢:)