如何让Pandas read_csv在列数变化时重新抛出解析错误?
解决CSV列数不一致时恢复解析错误的方案
方法1:切换到C引擎
Python引擎会自动补全缺失列,而C引擎默认会对列数不匹配的行抛出解析错误。直接修改代码:
df = pd.read_csv(files, header=1, sep=',', skiprows=0, engine='c', on_bad_lines='error')
执行后,遇到第2137行(列数变为105)时,会立刻触发ParserError,提示列数不一致,完全符合你需要的错误提示需求。注意C引擎仅支持单字符分隔符,你的逗号场景完全适用。
方法2:自定义行校验函数(保留Python引擎)
如果必须用Python引擎(比如需要支持复杂分隔符或其他特性),可以自定义on_bad_lines函数手动检查列数,不符合预期就主动抛出错误:
import pandas as pd def validate_columns(line): # 按逗号拆分行,统计当前列数 current_cols = len(line.split(',')) # 初始预期列数设为100,可根据实际调整 expected_cols = 100 if current_cols != expected_cols: raise ValueError(f"行列数异常:实际{current_cols}列,预期{expected_cols}列") df = pd.read_csv(files, header=1, sep=',', skiprows=0, engine='python', on_bad_lines=validate_columns)
这样只要行的列数不等于100,就会抛出错误,你可以捕获这个错误来定位列数变化的位置,后续拆分文件处理。
方法3:提前扫描文件定位变化点
如果想先找到列数变化的具体行号,再拆分文件分别读取,可以先逐行扫描CSV:
def find_column_switch(csv_file): with open(csv_file, 'r', encoding='utf-8') as f: # 跳过表头行(你设置header=1,所以文件第1行是表头) next(f) # 读取第一行数据,获取初始列数 first_data_line = next(f) expected_cols = len(first_data_line.split(',')) # 从第3行文件开始遍历(对应第2行数据),记录行号 for file_line_num, line in enumerate(f, start=3): current_cols = len(line.split(',')) if current_cols != expected_cols: return file_line_num, current_cols return None, None # 获取列数变化的文件行号和新列数 switch_line, new_col_count = find_column_switch(files) print(f"列数在文件第{switch_line}行变为{new_col_count}列")
拿到行号后,就可以拆分读取:
# 读取前2136行数据(文件第2行到第2137行) df_part1 = pd.read_csv(files, header=1, nrows=2136, sep=',', engine='python') # 读取后续行,跳过前2137行数据(文件前2138行:1行表头+2137行数据) df_part2 = pd.read_csv(files, header=1, skiprows=2137, sep=',', engine='python')
内容的提问来源于stack exchange,提问作者Josh M
相关产品推荐
相关产品推荐

