Python2中Pandas to_datetime转换9999-12-31时触发纳秒越界错误
我太懂这个坑了!在Python2对应的旧版Pandas里,用pd.to_datetime处理9999年这种极端日期确实会触发纳秒范围错误,核心原因是Pandas默认的datetime64[ns]类型有严格的范围限制——大概是公元1677年到2262年,9999年远远超出了这个区间。下面给你几个完整的解决方案,按需选择:
1. 直接保留原生datetime对象(最简单)
如果你不需要把这个日期转换成Pandas的Timestamp类型,只是想让转换操作不报错,直接用errors='ignore'参数就行。当转换失败时,Pandas会直接返回原来的Python原生datetime.datetime对象:
import pandas as pd big_date = pd.datetime(9999, 12, 31) big_date2 = pd.to_datetime(big_date, errors='ignore') print(big_date2) # 输出: 9999-12-31 00:00:00
这个方案的好处是零成本,缺点是返回的不是Pandas的时间类型,如果你后续要把它放到DataFrame里做时间相关的运算,可能会有兼容性问题。
2. 转换为低精度的Pandas时间类型
如果你需要把它转换成Pandas支持的时间类型,又不想丢失这个日期,可以降低时间精度,比如用微秒(datetime64[us])或者毫秒(datetime64[ms])来存储,这些类型的范围要宽得多:
# 方法1:先转字符串再解析,指定精度 big_date_str = big_date.strftime('%Y-%m-%d %H:%M:%S') big_date2 = pd.to_datetime(big_date_str).astype('datetime64[us]') # 方法2:直接构造低精度Timestamp from pandas import Timestamp big_date2 = Timestamp(big_date, unit='us')
这样得到的是Pandas的时间对象,能正常参与大部分时间运算,唯一的 trade-off 是精度从纳秒降到了微秒/毫秒,不过对于9999年这种远日期来说,这个精度损失基本可以忽略。
3. 数据框批量处理场景
如果是在DataFrame里批量处理这类极端日期,可以指定列的 dtype 为object来存储原生datetime对象,或者在pd.to_datetime里全局设置errors='ignore':
df = pd.DataFrame({'date': [big_date, pd.datetime(2020, 1, 1)]}) df['date'] = pd.to_datetime(df['date'], errors='ignore')
这样既保留了正常日期的Timestamp类型,又让极端日期以原生datetime的形式存在。
另外提一句,等你迁移到Python3和新版本Pandas后,这个问题会有所缓解——新版本对极端日期的处理更灵活,可能会自动降级精度或者提供更多参数选项,但上述方案在旧版本里依然是可靠的。
内容的提问来源于stack exchange,提问作者user7969724

