Pandas 无法识别 TZ 感知日期时间
Pandas not recognizing TZ aware datetime
我正在尝试编写一个脚本,该脚本接受一个日期和 returns 一个 pandas 数据框,其中包含索引的半小时内具有本地化日期时间的零。 SP是指结算周期,为半小时。这些脚本在大多数日子里都运行良好,但当它更改为夏令时或从夏令时更改时,我得到:
AmbiguousTimeError: Cannot infer dst time from '2017-10-29 01:00:00', try using the 'ambiguous' argument
这发生在行:
df_datetime.at[datetime, "Generation"] = 0
它尝试转换的日期是“2017-10-29 01:00:00”,即使给出的是“2017-10-29 01:00:00 + 1:00:00”,我会吗必须转换为 UTC=0,转换为 pandas,然后再次本地化? 2017年10月29日是英国夏令时结束的日子。
完整脚本如下:
import pandas as pd
from datetime import datetime, timedelta
import pytz
def SP_to_time_delta(SP):
dec_hour = (SP - 1)/2
hour = int(dec_hour)
if abs(int(dec_hour)-dec_hour) == 0.5:
minute = 30
else:
minute = 0
SP_timedelta = timedelta(hours=hour, minutes=minute)
return SP_timedelta
def localize_datetime_UK(date, SP):
pytz_tz = pytz.timezone('Europe/London')
local_date = pytz_tz.localize(date)
SP_timedelta = SP_to_time_delta(SP)
local_datetime = local_date+SP_timedelta
return local_datetime
def get_datetime_df(SettlementDate, max_SP):
df_datetime = pd.DataFrame([])
for i in range(max_SP+1):
datetime = localize_datetime_UK(SettlementDate, i)
df_datetime.at[datetime, "Generation"] = 0
df_datetime = df_datetime.sort_index()
return df_datetime
SettlementDate = datetime(2017, 10, 29)
df_datetime = get_datetime_df(SettlementDate, 50)
解决这个问题的最佳方法是什么?
感谢所有回复和帮助!
您的问题源于夏令时的混淆。考虑以下因素:
import pandas as pd
from datetime import datetime, timedelta
import pytz
pytz_tz = pytz.timezone('Europe/London')
datetime_1 = pytz_tz.localize(datetime(2017, 10, 29) \
+ timedelta(hours=0, minutes=0))
datetime_2 = pytz_tz.localize(datetime(2017, 10, 29) \
+ timedelta(hours=1, minutes=0))
print(datetime_1)
print(datetime_2)
> 2017-10-29 00:00:00+01:00
> 2017-10-29 01:00:00+00:00
如您所见,您处理的时间点是 "same" 的两倍,但编码不同。
一种解决方案是将所有时间转换为 UTC(没有夏令时),并且仅在需要输出时将时间转换回来。
但是,我认为您在错误的地方添加了 timedelta。考虑
datetime_1 = pytz_tz.localize(datetime(2017, 10, 29)) \ # localize first
+ timedelta(hours=0) # then add the delta
datetime_2 = pytz_tz.localize(datetime(2017, 10, 29)) \ # localize first
+ timedelta(hours=1) # then add the delta
> 2017-10-29 00:00:00+01:00
> 2017-10-29 01:00:00+01:00
产生独特的结果。检查应用程序的语义,哪个版本适用。
=====旧答案======
您必须使用
让日期时间对象识别时区
from datetime import datetime, timedelta
from pytz import timezone
import pytz
eastern = timezone('US/Eastern')
SelltementDate = eastern.localize(datetime(2017, 10, 29, 0, 0, 0))
我正在尝试编写一个脚本,该脚本接受一个日期和 returns 一个 pandas 数据框,其中包含索引的半小时内具有本地化日期时间的零。 SP是指结算周期,为半小时。这些脚本在大多数日子里都运行良好,但当它更改为夏令时或从夏令时更改时,我得到:
AmbiguousTimeError: Cannot infer dst time from '2017-10-29 01:00:00', try using the 'ambiguous' argument
这发生在行:
df_datetime.at[datetime, "Generation"] = 0
它尝试转换的日期是“2017-10-29 01:00:00”,即使给出的是“2017-10-29 01:00:00 + 1:00:00”,我会吗必须转换为 UTC=0,转换为 pandas,然后再次本地化? 2017年10月29日是英国夏令时结束的日子。
完整脚本如下:
import pandas as pd
from datetime import datetime, timedelta
import pytz
def SP_to_time_delta(SP):
dec_hour = (SP - 1)/2
hour = int(dec_hour)
if abs(int(dec_hour)-dec_hour) == 0.5:
minute = 30
else:
minute = 0
SP_timedelta = timedelta(hours=hour, minutes=minute)
return SP_timedelta
def localize_datetime_UK(date, SP):
pytz_tz = pytz.timezone('Europe/London')
local_date = pytz_tz.localize(date)
SP_timedelta = SP_to_time_delta(SP)
local_datetime = local_date+SP_timedelta
return local_datetime
def get_datetime_df(SettlementDate, max_SP):
df_datetime = pd.DataFrame([])
for i in range(max_SP+1):
datetime = localize_datetime_UK(SettlementDate, i)
df_datetime.at[datetime, "Generation"] = 0
df_datetime = df_datetime.sort_index()
return df_datetime
SettlementDate = datetime(2017, 10, 29)
df_datetime = get_datetime_df(SettlementDate, 50)
解决这个问题的最佳方法是什么?
感谢所有回复和帮助!
您的问题源于夏令时的混淆。考虑以下因素:
import pandas as pd
from datetime import datetime, timedelta
import pytz
pytz_tz = pytz.timezone('Europe/London')
datetime_1 = pytz_tz.localize(datetime(2017, 10, 29) \
+ timedelta(hours=0, minutes=0))
datetime_2 = pytz_tz.localize(datetime(2017, 10, 29) \
+ timedelta(hours=1, minutes=0))
print(datetime_1)
print(datetime_2)
> 2017-10-29 00:00:00+01:00
> 2017-10-29 01:00:00+00:00
如您所见,您处理的时间点是 "same" 的两倍,但编码不同。
一种解决方案是将所有时间转换为 UTC(没有夏令时),并且仅在需要输出时将时间转换回来。
但是,我认为您在错误的地方添加了 timedelta。考虑
datetime_1 = pytz_tz.localize(datetime(2017, 10, 29)) \ # localize first
+ timedelta(hours=0) # then add the delta
datetime_2 = pytz_tz.localize(datetime(2017, 10, 29)) \ # localize first
+ timedelta(hours=1) # then add the delta
> 2017-10-29 00:00:00+01:00
> 2017-10-29 01:00:00+01:00
产生独特的结果。检查应用程序的语义,哪个版本适用。
=====旧答案======
您必须使用
让日期时间对象识别时区from datetime import datetime, timedelta
from pytz import timezone
import pytz
eastern = timezone('US/Eastern')
SelltementDate = eastern.localize(datetime(2017, 10, 29, 0, 0, 0))