首页 > 解决方案 > 处理 DST 调整的时间数据

问题描述

我有一个数据集,其中包含 5 年每小时的数据。每个数据点都有一个日期 - 我想包含一个指定小时数的列,即 00-01 是小时 #1,01-02 是小时 #2 等等。

但是,该数据集包括夏季/冬季时间,即,由于将时间提前设置为一小时,3 月的某天有一个空白时间。此外,它包括一年中的一天,其中包含 25 小时,因为冬季时间倒退。

任何人都可以帮我制作一个每天计数 1-24 的专栏,它仍然占夏季/冬季时间。我在想一个计数器,它可以连续计算一个日期“到目前为止”发生了多少次

期望的输出:

          Date  Year  Month  Day  Weekday  Hour
0   01-01-2015  2015      1    1        4     1
1   01-01-2015  2015      1    1        4     2
2   01-01-2015  2015      1    1        4     3
3   01-01-2015  2015      1    1        4     4
4   01-01-2015  2015      1    1        4     5
5   01-01-2015  2015      1    1        4     6
6   01-01-2015  2015      1    1        4     7
7   01-01-2015  2015      1    1        4     8
8   01-01-2015  2015      1    1        4     9
9   01-01-2015  2015      1    1        4    10
10  01-01-2015  2015      1    1        4    11
11  01-01-2015  2015      1    1        4    12
12  01-01-2015  2015      1    1        4    13
13  01-01-2015  2015      1    1        4    14
14  01-01-2015  2015      1    1        4    15

           Dates  Year  Month  Weekday  Hour  ...    NO1    NO2    NO5    NO3    NO4
2088  29-03-2015  2015      3        7     1  ...  22.90  22.90  22.90  22.90  22.90
2089  29-03-2015  2015      3        7     2  ...  22.37  22.37  22.37  22.37  22.37
2090  29-03-2015  2015      3        7     3  ...    NaN    NaN    NaN    NaN    NaN
2091  29-03-2015  2015      3        7     4  ...  21.94  21.94  21.94  22.03  22.03
2092  29-03-2015  2015      3        7     5  ...  21.52  21.52  21.52  22.01  22.01
           Dates  Year  Month  Weekday  Hour  ...    NO1    NO2    NO5    NO3    NO4
7128  25-10-2015  2015     10        7     1  ...  22.39  22.39  22.39  22.39  22.39
7129  25-10-2015  2015     10        7     2  ...  22.02  22.02  22.02  21.54  21.54
7130  25-10-2015  2015     10        7     3  ...  21.99  21.99  21.99  20.82  20.82
7131  25-10-2015  2015     10        7     4  ...  21.99  21.99  21.99  20.77  20.77
7132  25-10-2015  2015     10        7     5  ...  21.80  21.80  21.80  20.11  20.11

标签: pythonpandasdataframedatedatetime

解决方案


首先,我会删除带有NaN值的行,因为这些行来自不存在的时间(DST 转换):

import pandas as pd
import numpy as np

# mre / dummy data
df = pd.DataFrame({
    'Date': ["29-03-2015", "29-03-2015", "29-03-2015", "29-03-2015", "29-03-2015",
             "25-10-2015", "25-10-2015", "25-10-2015", "25-10-2015", "25-10-2015"],
    'Value': [1, 2, np.NaN, 4, 5,
              1, 2, 3, 4, 5]
    })

# drop all rows with NaN values; adjust if needed!
df = df.dropna()

现在您可以根据日期重新计算小时:

# recalculate the hour of day, zero-based
datechange = df['Date'].eq(df['Date'].shift())
df['Hour_New'] = datechange.cumsum() - datechange.cumsum().where(~datechange).ffill()

# df
#          Date  Value  Hour_New
# 0  29-03-2015    1.0       0.0
# 1  29-03-2015    2.0       1.0
# 3  29-03-2015    4.0       2.0
# 4  29-03-2015    5.0       3.0
# 5  25-10-2015    1.0       0.0
# 6  25-10-2015    2.0       1.0
# 7  25-10-2015    3.0       2.0
# 8  25-10-2015    4.0       3.0
# 9  25-10-2015    5.0       4.0

...这使您能够计算时区感知日期时间:

zone = 'Europe/Copenhagen'
# begin with date, localized to origin time zone
df['datetime'] = pd.to_datetime(df['Date'], dayfirst=True).dt.tz_localize(zone)
# now add the hour as a timedelta
df['datetime'] += pd.to_timedelta(df['Hour_New'], unit='h')

# df['datetime']
# 0   2015-03-29 00:00:00+01:00
# 1   2015-03-29 01:00:00+01:00
# 3   2015-03-29 03:00:00+02:00 # <-- one hour stolen due to DST transition
# 4   2015-03-29 04:00:00+02:00
# 5   2015-10-25 00:00:00+02:00
# 6   2015-10-25 01:00:00+02:00
# 7   2015-10-25 02:00:00+02:00
# 8   2015-10-25 02:00:00+01:00 # <-- duplicate hour due to DST transition
# 9   2015-10-25 03:00:00+01:00
# Name: datetime, dtype: datetime64[ns, Europe/Copenhagen]

推荐阅读