含无效时间戳时pandas.read_sas()读取失败,求解决方法
解决pandas读取含无效时间戳的sas7bdat文件报错问题
问题原因
报错源于文件中存在超出pandas datetime范围的极端时间戳(比如R中显示的-3219212-04-24),pandas默认的日期转换逻辑无法处理这类超范围数值,触发溢出错误。而R的haven包会自动将无效时间戳识别为NA,因此能正常读取。
解决方案
以下是几种可行的解决方法,按推荐度排序:
方法1:使用pyreadstat库(推荐)
pyreadstat是专门处理SAS/SPSS/Stata文件的第三方库,对无效日期的处理更灵活,支持直接将无效值转为NaT:
import pyreadstat # 读取文件,自动将无效日期转为NaT df, meta = pyreadstat.read_sas7bdat( 'my_sas_file.sas7bdat', convert_dates=True, invalidates='coerce' # 关键参数:强制将无效日期转为NaT )
方法2:pandas读取时跳过自动转换,手动处理
利用pandas的convert_datetimes=False参数,先读取原始的日期数值(SAS中日期以1960-01-01为起点,存储为秒数),再手动转换并捕获异常:
import pandas as pd from datetime import datetime, timedelta # 读取时不自动转换日期,保留原始秒数值 df = pd.read_sas('my_sas_file.sas7bdat', convert_datetimes=False) # 定义安全转换函数,异常时返回NaT def safe_convert_sas_dt(sas_seconds): try: return datetime(1960, 1, 1) + timedelta(seconds=sas_seconds) except (OverflowError, ValueError): return pd.NaT # 对目标日期列应用转换 df['DtObgnOrig'] = df['DtObgnOrig'].apply(safe_convert_sas_dt)
方法3:使用sas7bdat第三方库
如果上述方法不适用,可尝试sas7bdat库读取原始数据后处理:
from sas7bdat import SAS7BDAT import pandas as pd from datetime import datetime, timedelta with SAS7BDAT('my_sas_file.sas7bdat') as sas_file: df = sas_file.to_dataframe(convert_dates=False) # 应用安全转换函数处理日期列 df['DtObgnOrig'] = df['DtObgnOrig'].apply(safe_convert_sas_dt)
验证结果
处理后可通过df['DtObgnOrig'].isna().sum()查看被转为NaT的无效时间戳数量,结果应与R中显示的NA数量(93215826)一致。
内容的提问来源于stack exchange,提问作者Gopala
相关产品推荐
相关产品推荐

