python - 处理 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
解决方案
首先,我会删除带有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]
推荐阅读
- typescript - 在 Typescript 中修改数组的类型
- azure - Azure 持久功能编排触发器不触发
- swift - UICollectionViewCompositionalLayout 具有自调整大小的单元格
- node.js - Node.js 异步 for 循环未运行
- android - Android 是否有折叠视图或手风琴视图的标准布局?
- javascript - 如何从nodejs中的内部函数调用外部函数?我正在为 Google 对话流实现编码
- java - 使用 if-else 防止字符串在 JTextfield 中为空
- javascript - 在 webpack 中使用 lottie 库?
- javascript - 格式化来自 AWS Lambda 函数的文本响应
- html - 文本未显示在边框 html/css