Pandas使用apply调用tz_convert返回object而非datetime类型问题
解决按行转换时区后保留datetime类型及时区信息的问题
针对你遇到的情况,分两种场景给你具体解决方案:
场景1:所有行的时区偏移量固定
如果你的time_zone + daylight_saving在整个DataFrame中是同一个值,完全没必要用apply逐行处理——直接统一转换时区效率更高,还能直接得到带时区的datetime类型结果:
import pandas as pd import pytz # 计算总偏移量(取第一行的值即可,因为所有行相同) total_offset = df['time_zone'].iloc[0] + df['daylight_saving'].iloc[0] # 转换为目标时区 local_df = df.tz_convert(pytz.FixedOffset(total_offset)) # 查看结果索引类型 print(local_df.index)
输出会是带明确时区的DatetimeIndex,完全符合你的预期:
DatetimeIndex(['2017-06-02 01:00:00+01:00', '2017-06-02 02:00:00+01:00', '2017-06-02 03:00:00+01:00', '2017-06-02 04:00:00+01:00', '2017-06-02 05:00:00+01:00'], dtype='datetime64[ns, pytz.FixedOffset(60)]', name='END_DATE', freq=None)
场景2:时区偏移量随行变化
如果不同行的偏移量不一样,apply返回object类型是因为pandas无法用单一的时区datetime dtype存储不同时区的datetime对象。不过不用担心,这些object类型的元素本质还是带时区的datetime对象,完全可以正常进行时间运算(比如比较、加减)。
如果你想显式确保结果能被识别为datetime相关类型,或者避免用pd.to_datetime时转回UTC,可以这样做:
# 逐行转换时区 local_times = df.apply( lambda r: r.name.tz_convert(pytz.FixedOffset(r['time_zone'] + r['daylight_saving'])), axis=1 ) # 方法1:如果所有元素时区一致,用pd.to_datetime并指定utc=False if all((df['time_zone'] + df['daylight_saving']) == (df['time_zone'] + df['daylight_saving']).iloc[0]): local_times = pd.to_datetime(local_times, utc=False) print(local_times.dtype) # datetime64[ns, pytz.FixedOffset(60)] # 方法2:如果时区有差异,保留object类型但确保元素是datetime对象 # 此时虽然dtype是object,但每个元素都是带时区的datetime,不影响使用 print(local_times.iloc[0].tz) # 可以正常获取时区信息 print(local_times.iloc[1] - local_times.iloc[0]) # 正常计算时间差
为什么之前用pd.to_datetime会转回UTC?
因为pd.to_datetime默认会尝试将datetime转换为UTC时区(当输入包含时区信息时),只要显式指定utc=False,就能保留原有的时区信息,不会被强制转回UTC。
内容的提问来源于stack exchange,提问作者lgg
相关产品推荐
相关产品推荐

