【问题标题】:Process time data with adjustments for DST处理 DST 调整的时间数据
【发布时间】:2021-08-18 11:49:24
【问题描述】:

我有一个数据集,其中包含 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

【问题讨论】:

  • 如果您的数据不需要夏令时,您不能通过将 3 月和 10 月之间的日期移动 1 小时来将其从数据集中删除
  • 我直接从网站下载数据集,因此该方法必须足够动态以能够处理夏令时
  • 您需要了解生成数据所在区域的夏令时规则;那么将所有内容标准化为 UTC 应该很容易。
  • 我知道它会在 3 月的最后一个星期日和 10 月的最后一个星期日发生变化 - 不过我不知道如何转换
  • 感谢您的更新;但我必须再次要求澄清。您能否更改数据示例以显示 2015-10-25 小时 1-5 小时(DST 转换 +1 小时)以及 2015-03-29 小时 1-5 小时(DST 转换 -1 小时)的数据外观?另外,为了确定,GMT+2 是 UTC 偏移量 - time zone 是什么?

标签: python pandas dataframe date datetime


【解决方案1】:

首先,我会删除带有 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]

【讨论】:

  • 谢谢。完成此操作后,只需进行少量编辑(转换回仅一个小时)就可以了!
【解决方案2】:

能否将列转换为日期时间,然后从日期时间中提取小时?

然后删除任何 0 或 25 小时,使您的所有日子都变成 24 小时。

提示使用 pandas 日期时间将列转换为日期时间,然后使用小时函数创建一个新列。

【讨论】:

  • 首先,我可以转换为日期时间——但数据不包含小时戳——如果原始数据不包含小时戳,我不知道如何转换为小时。而且我仍然会保留时间 - 我只需要知道时间适合 3 年后以及第一个 .hour 函数只返回 0s
  • 如果小时为 25,您甚至无法转换为日期时间 - 这里只允许 0 - 23 小时。
  • 这就是为什么我开始要求帮助我制作某种计数器,可以计算“直到现在”特定日期的出现次数。比如“在这一行和第一行之间,这一行中的日期出现了多少次。这有意义吗?
猜你喜欢
  • 2013-02-21
  • 2016-07-29
  • 1970-01-01
  • 2011-10-11
  • 2012-04-05
  • 2013-02-09
  • 2016-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多