如何优雅处理Pandas read_csv不透明迭代器抛出的异常?
处理Pandas Chunk迭代器抛出的ParserError问题
我完全懂你的痛点——用C引擎读大CSV本来就是奔着速度去的,结果遇到损坏的文件,迭代器直接炸了,error_bad_lines=False也救不了,换Python引擎又慢得让人抓狂。
你之前的代码问题在于:异常是迭代器在生成下一个chunk的时候抛出的,而不是在处理已经拿到的chunk时。for循环会自动调用next(),这个过程不在你的try块里,所以异常直接跳出循环了。要解决这个,得把try-except包裹在获取下一个chunk的步骤上,而不是处理chunk的步骤。
这里有两个实用的方案,都能保留C引擎的速度:
方案一:手动迭代,用while循环捕获异常
直接手动控制迭代流程,把next()调用放在try块里,这样就能捕获迭代器抛出的异常:
import pandas as pd import pandas.errors # 初始化chunk迭代器 chunk_iter = pd.read_csv("your_corrupted_file.csv", chunksize=10000, error_bad_lines=False) while True: try: chunk = next(chunk_iter) # 处理你的chunk数据 print(f"Processed chunk with {len(chunk)} rows") except StopIteration: # 迭代器正常结束,退出循环 break except pandas.errors.ParserError: # 遇到解析错误,跳过当前chunk,继续下一个 print("Skipping corrupted chunk...") continue
这个方案很直观,完全控制迭代流程,遇到ParserError就跳过,直到迭代器正常结束或者你主动终止。
方案二:写一个安全迭代器包装器
如果要处理多个文件,或者想复用逻辑,可以写一个通用的包装函数,把任何迭代器转换成能捕获指定异常的安全迭代器:
import pandas as pd import pandas.errors def safe_iter(iterator, skip_exceptions=(pandas.errors.ParserError,)): while True: try: yield next(iterator) except StopIteration: return except skip_exceptions as e: print(f"Skipping exception: {type(e).__name__}") continue # 使用包装后的迭代器 chunk_iter = pd.read_csv("your_corrupted_file.csv", chunksize=10000, error_bad_lines=False) safe_chunk_iter = safe_iter(chunk_iter) for chunk in safe_chunk_iter: # 处理chunk数据 print(f"Processed chunk with {len(chunk)} rows")
这个包装器把异常处理逻辑封装起来,用起来和普通迭代器一样方便,还能自定义要跳过的异常类型。
补充说明
- 为什么
error_bad_lines=False没用?因为这个参数是让Pandas跳过单个坏行,但你遇到的是EOF在字符串内部的问题,这属于文件级别的损坏,C引擎会直接抛出ParserError而不是跳过行。 - 如果你不想跳过而是直接终止文件读取,把
continue换成break就行,这样遇到第一个损坏的chunk就停止处理当前文件。
内容的提问来源于stack exchange,提问作者Stephen
相关产品推荐
相关产品推荐

