升级Pandas后出现“.dt访问器仅支持类时间值”错误求助
问题分析与解决方案
这是Pandas版本升级后的已知行为差异,并非bug,核心原因是Pandas 1.0+版本对带时区的datetime列合并逻辑做了调整,和0.24.x的处理规则存在明显区别:
为什么合并后time列变成object类型?
在Pandas 0.24.x中,只要两个datetime列的时区名称一致(比如都是US/Eastern),merge后会保留datetime64[ns, US/Eastern]类型。但从Pandas 1.0开始,merge时会严格检查时区对象的同一性(即两个列的时区是否是同一个Python实例),而不仅仅是时区名称相同。
哪怕两个列的时区名称都是US/Eastern,只要一个是通过pytz.timezone('US/Eastern')创建的,另一个是dateutil.tz.gettz('US/Eastern')创建的,或者其中一个是从外部数据读取自动解析的、另一个是手动指定的,merge后都会因为时区实例不匹配,导致列类型退化为object。
解决方法
1. 合并前统一时区实例
确保两个DataFrame的time列使用完全相同的时区对象:
import pytz tz = pytz.timezone('US/Eastern') # 重新设置两个列的时区,覆盖原有时区实例 df['time'] = df['time'].dt.tz_convert(tz) another_df['time'] = another_df['time'].dt.tz_convert(tz) # 再执行合并操作 df = pd.merge( df, another_df[["time", "col1", "col2"]], # 替换为你的实际列名 on=["time"], how="left", )
2. 合并后强制转换类型
如果合并后已经变成object类型,直接重新转换为带时区的datetime:
# 若原数据是带时区的datetime值,重新指定时区 df['time'] = pd.to_datetime(df['time']).dt.tz_localize('US/Eastern', ambiguous='infer') # 若原数据是带时区的字符串,直接指定tz参数 # df['time'] = pd.to_datetime(df['time'], tz='US/Eastern')
3. 验证时区实例是否一致
合并前可以先检查两个列的时区是否为同一个实例,快速定位问题:
print(df['time'].dt.tz is another_df['time'].dt.tz)
如果输出False,就说明时区实例不匹配,是导致问题的直接原因,按方法1处理即可。
内容的提问来源于stack exchange,提问作者h8n2
相关产品推荐
相关产品推荐

