pandas两日期列相减在Databricks报Python int转C long错误
问题描述
- 现有基于pandas的日期计算逻辑,自定义随机日期生成函数及DataFrame初始化代码如下:
from datetime import date, timedelta import pandas as pd import random def dates(start_date, end_date): start_date = date(start_date[0], start_date[1], start_date[2]) end_date = date(end_date[0], end_date[1], end_date[2]) days_delta = (end_date - start_date).days return start_date + timedelta(days=random.randrange(days_delta)) df = pd.DataFrame(index=range(100)) df['MOVE_OUT_DATE'] = date(9999, 12, 31) df['MOVE_IN_DATE'] = [dates((2021, 1, 1), (2021, 6, 30)) for _ in range(df.shape[0])]
- 执行日期差计算代码:
df['days_diff'] = df['MOVE_OUT_DATE'] - df['MOVE_IN_DATE'] - 运行现象:代码在VS Code环境可正常执行,在Databricks环境运行时抛出 Python int too large to convert to C long 错误。
问题根因
报错本质是类型溢出:
- Databricks runtime预装的pandas多为1.x版本,日期类型默认使用
datetime64[ns](纳秒级精度),该类型可表示的最大日期为2262年4月11日,9999-12-31超出该范围,转成纳秒时间戳时数值会超过C语言long类型的取值上限,触发报错。 - 本地VS Code环境如果安装了pandas 2.0+版本,会自动根据日期范围选择适配的datetime精度(如微秒、毫秒级),可支持的最大日期远超过9999年,因此不会触发该错误。
解决方法
可根据实际场景选择以下任意一种方案:
- 显式指定日期列使用非纳秒精度的datetime类型,从根源避开纳秒类型的范围限制,执行日期计算前先做类型转换:
# 微秒精度datetime可支持到约公元294247年,完全覆盖9999年的占位日期 df['MOVE_OUT_DATE'] = pd.to_datetime(df['MOVE_OUT_DATE'], dtype='datetime64[us]') df['MOVE_IN_DATE'] = pd.to_datetime(df['MOVE_IN_DATE'], dtype='datetime64[us]') df['days_diff'] = df['MOVE_OUT_DATE'] - df['MOVE_IN_DATE']
- 替换远期占位日期:将
MOVE_OUT_DATE列的默认值从9999-12-31换成datetime64[ns]支持范围内的日期(如2260-12-31),无需调整类型即可正常计算。 - 升级Databricks环境的pandas版本到2.0及以上,高版本pandas会自动匹配日期精度,不会强制使用纳秒类型触发溢出。
- 走Python原生运算逻辑绕过C层类型转换:直接用apply逐行调用原生date对象做差,避免pandas自动转datetime64[ns]的逻辑:
df['days_diff'] = df.apply(lambda x: x['MOVE_OUT_DATE'] - x['MOVE_IN_DATE'], axis=1)
内容的提问来源于stack exchange,提问作者Amit Singh
相关产品推荐
相关产品推荐

