pandas遍历读取文件夹所有SPSS文件拼接时日期溢出报错如何解决
问题原因排查
你写的代码本身存在2个基础错误,同时触发日期溢出报错的根源是部分SAV文件存在超出pandas日期类型支持范围的异常值:
- 路径写法错误:
r'\C:\abc\path'开头多了冗余反斜杠,会导致glob匹配文件路径异常 - 列表追加逻辑错误:循环里
df_list.append(filename)追加的是文件路径字符串,不是读取得到的DataFrame,即使不抛日期错误,后续拼接也会报类型错误 - 日期溢出原因:单独读取第一个文件正常,说明后续某一个SAV文件中存在超出pandas datetime64类型支持范围的日期值。SPSS日期以1582年10月14日为时间原点存储秒数,而pandas datetime64最早仅支持到1677年9月,文件中录入错误的极端早日期、历史遗留的异常日期值都会触发
OverflowError: date value out of range报错。
修复方案
直接用以下代码即可实现批量读取合并,同时绕过日期溢出问题:
import glob import pandas as pd import pyreadstat # 修正路径,删除开头多余的反斜杠 path = r'C:\abc\path' all_files = glob.glob(path + r"\*.sav") df_list = [] for file_path in all_files: # 关闭自动日期转换,先按原始值读取,避免读取阶段直接抛出溢出错误 df, _ = pyreadstat.read_sav( file_path, convert_categoricals=False, dates_as_pandas_datetime=False ) # 增加来源文件列,方便后续排查异常数据 df['source_file'] = file_path.split("\\")[-1] df_list.append(df) # 合并所有数据,重置索引 final_df = pd.concat(df_list, ignore_index=True)
如果后续需要转换日期列,可以先过滤掉超出合法范围的异常值再做类型转换,示例逻辑:
# 替换成你自己的日期列名 date_columns = ["start_date", "end_date"] # pandas支持的最早日期对应SPSS存储的秒数阈值 min_valid_ts = (pd.Timestamp("1677-09-21") - pd.Timestamp("1582-10-14")).total_seconds() for col in date_columns: # 超出范围的异常值设为空值 final_df.loc[final_df[col] < min_valid_ts, col] = pd.NA # 按SPSS日期规则转换为pandas时间类型 final_df[col] = pd.to_datetime(final_df[col], unit="s", origin="1582-10-14")
如果需要快速定位是哪个文件存在异常日期,可以在读取循环里加异常捕获:
for file_path in all_files: try: test_df = pd.read_spss(file_path, convert_categoricals=False) print(f"正常读取:{file_path}") except OverflowError: print(f"存在异常日期的问题文件:{file_path}") break
内容的提问来源于stack exchange,提问作者Farrukh Khan
相关产品推荐
相关产品推荐

