使用tz_localize与ZoneInfo时UTC偏移错误的解决方法
解决pandas 1.5.3中ZoneInfo本地化夏令时重复时间的偏移错误
问题原因
pandas 1.5.x版本对ZoneInfo对象的ambiguous='infer'参数支持存在缺陷,无法正确推断夏令时切换时重复本地时间对应的UTC偏移。而直接传入时区字符串时,pandas内部会 fallback 到pytz处理推断逻辑,因此结果正确。
解决方案(无需升级pandas)
手动生成ambiguous参数所需的布尔列表,明确标记重复时间对应的时区偏移归属:
import pandas as pd from zoneinfo import ZoneInfo # 复现无时区的DatetimeIndex pd_local_no_tz = pd.date_range('2023-10-29', '2023-10-30', freq='H', tz=ZoneInfo('Europe/Amsterdam')).tz_localize(None) # 生成ambiguous列表:重复时间中,首次出现的对应夏令时(+02:00,标记为True),第二次对应标准时(+01:00,标记为False) ambiguous = ~pd_local_no_tz.duplicated(keep='first') # 使用ZoneInfo完成本地化 pd_local = pd_local_no_tz.tz_localize(ZoneInfo('Europe/Amsterdam'), ambiguous=ambiguous) # 验证结果 print(pd_local[[4,5]]) # 预期输出: # DatetimeIndex(['2023-10-29 02:00:00+02:00', '2023-10-29 02:00:00+01:00'], dtype='datetime64[ns, Europe/Amsterdam]', freq=None)
原理说明
pd_local_no_tz.duplicated(keep='first')会标记除首次出现外的重复项为True,取反后得到的列表中,首次重复项为True(对应夏令时偏移),第二次为False(对应标准时偏移)。tz_localize的ambiguous参数接受布尔列表时,True表示该时间属于夏令时(UTC偏移更大的时段),False表示属于标准时(UTC偏移更小的时段)。
替代方案(若允许升级pandas)
升级到pandas 2.0及以上版本,该版本已完善对ZoneInfo的ambiguous='infer'支持,直接执行你原本的代码即可得到正确结果:
pd_local = pd_local_no_tz.tz_localize(ZoneInfo('Europe/Amsterdam'), ambiguous='infer')
内容的提问来源于stack exchange,提问作者Markus
相关产品推荐
相关产品推荐

