Sea*_*thy 7 python pytz python-3.x pandas
我创建了一个每小时日期数据框,现在我想创建一个列来标记每行(小时)是否处于夏令时。例如,在夏季,该标志应 == 1,而在冬季,该标志应 == 0。
# Localized dates dataframe
dates = pd.DataFrame(data=pd.date_range('2018-1-1', '2019-1-1', freq='h', tz='America/Denver'), columns=['date_time'])
# My failed attempt to create the flag column
dates['dst_flag'] = np.where(dates['date_time'].dt.daylight_saving_time == True, 1, 0)
Run Code Online (Sandbox Code Playgroud)
评论中有一个很好的链接,至少可以让您手动执行此操作。AFAIK,没有矢量化的方法可以做到这一点。
import pandas as pd
import numpy as np
from pytz import timezone
# Generate data (as opposed to index)
date_range = pd.to_datetime(pd.date_range('1/1/2018', '1/1/2019', freq='h', tz='America/Denver'))
date_range = [date for date in date_range]
# Localized dates dataframe
df = pd.DataFrame(data=date_range, columns=['date_time'])
# Map transition times to year for some efficiency gain
tz = timezone('America/Denver')
transition_times = tz._utc_transition_times[1:]
transition_times = [t.astimezone(tz) for t in transition_times]
transition_times_by_year = {}
for start_time, stop_time in zip(transition_times[::2], transition_times[1::2]):
year = start_time.year
transition_times_by_year[year] = [start_time, stop_time]
# If the date is in DST, mark true, else false
def mark_dst(dates):
for date in dates:
start_dst, stop_dst = transition_times_by_year[date.year]
yield start_dst <= date <= stop_dst
df['dst_flag'] = [dst_flag for dst_flag in mark_dst(df['date_time'])]
# Do a quick sanity check to make sure we did this correctly for year 2018
dst_start = df[df['dst_flag'] == True]['date_time'][0] # First dst time 2018
dst_end = df[df['dst_flag'] == True]['date_time'][-1] # Last dst time 2018
print(dst_start)
print(dst_end)
Run Code Online (Sandbox Code Playgroud)
这输出:
2018-03-11 07:00:00-06:00
2018-11-04 06:00:00-07:00
Run Code Online (Sandbox Code Playgroud)
这可能是正确的。我没有手动进行 UTC 转换或任何检查时间是否与给定时区完全正确的操作。您至少可以通过快速谷歌搜索来验证日期是否正确。
pd.date_range
生成索引,而不是数据。我稍微更改了您的原始代码,使其成为数据而不是索引。我假设你已经有了数据。
其结构有些愚蠢tz._utc_transition_times
。这是开始/停止 utc DST 转换时间,但早期日期中有一些愚蠢的东西。不过从1965年开始应该就不错了。如果您的日期早于该日期,请更改tz._utc_transition_times[1:]
为tz._utc_transition_times
. 请注意,并非 1965 年之前的所有年份都存在。
tz._utc_transition_times
是“Python私有”。它可能会在没有警告或通知的情况下进行更改,并且可能适用于未来或过去的版本pytz
。我使用的是pytz
2017.3版本。我建议您运行此代码以确保输出匹配,如果不匹配,请确保使用版本 2017.3。
HTH,祝您的研究/回归问题好运!