将SAS生成的CSV导入Pandas时自定义日期解析函数报错问题
解决SAS日期时间在Pandas read_csv中解析失败的问题
我之前也碰到过一模一样的情况:单独测试解析函数完全正常,但一放到pd.read_csv()里就疯狂报错。核心问题其实是传入解析函数的参数和你单独测试时的类型、格式完全不一样,结合你的代码,我整理了几个关键的排查点和解决方案:
1. 先搞懂date_parser实际接收到的是什么值
你单独测试时传的是整数1652745600,但CSV里的日期值大概率是字符串形式(比如"1652745600"),甚至可能是带小数的字符串(比如"1652745600.0"——SAS有时候会输出浮点数格式的日期),或者存在空值、无效字符。
你的原函数直接执行int(d),如果d是带小数的字符串,立刻就会抛出ValueError,这就是你看到反复打印错误的原因。
2. 修改解析函数,兼容更多场景
更新你的parse_date函数,处理空值、字符串转数字、带小数的情况,同时捕获更多异常并返回缺失值避免中断:
import pandas as pd import datetime as dt def parse_date(d): # 先处理空值或空白字符串 if pd.isna(d) or str(d).strip() == '': return pd.NaT try: # 先转成float再转int,兼容带小数的数字/字符串 secs = int(float(d)) return dt.timedelta(seconds=secs) + dt.datetime(1960, 1, 1) except (ValueError, TypeError) as e: # 打印出错的具体值,方便精准排查 print(f"解析失败:值为 {repr(d)},错误信息:{e}") return pd.NaT
3. 更稳妥的替代方案:先读数据再单独转换日期列
有时候date_parser的行为会因为pandas版本、parse_dates的参数形式(列索引/列名)出现预期外的问题,你可以放弃用date_parser,先读取原始数据,再对指定列单独做转换,这样可控性更强:
def get_ods_reader(): # 先不解析日期,只指定dtype和converters ods_reader = pd.read_csv( "mycsv.csv", chunksize=200000, dtype={"account_nbr": object, "REPOSSESSION_STATUS_CD": object}, converters={"repossession_ind": parse_int} ) return ods_reader # 处理每个chunk的日期列 chunk_dtypes = [] date_cols = [6, 9, 10, 16] # 你指定的日期列索引 for chunk in get_ods_reader(): for col_idx in date_cols: # 对列中的每个值做转换 chunk.iloc[:, col_idx] = chunk.iloc[:, col_idx].apply( lambda x: dt.timedelta(seconds=int(float(x))) + dt.datetime(1960, 1, 1) if pd.notna(x) and str(x).strip() != '' else pd.NaT ) print(chunk.head(5)) chunk_dtypes.append(chunk.dtypes)
4. 排查无效值的小技巧
如果修改后还是有错误,建议先打印出原始日期列的前几行,看看是不是存在非数字的奇怪值:
# 在读取chunk后先打印原始日期列 for chunk in get_ods_reader(): print("原始日期列值:") for col_idx in date_cols: print(chunk.iloc[:, col_idx].head(10)) # 再做转换...
这样你就能精准定位到哪些值导致了解析失败,针对性处理。
内容的提问来源于stack exchange,提问作者CrunchyCruncha
相关产品推荐
相关产品推荐

