UnicodeDecodeError问题:单CSV文件读取失败的排查与解决
问题描述
批量读取CSV文件时,仅单个文件触发UnicodeDecodeError,错误信息:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb0 in position 31: invalid start byte
使用的代码:
import os import pandas as pd data_dir = 'C:/Users\ebook\Downloads\Batch One Set\Sample Output' for filepath in os.listdir(data_dir): splitstr = filepath.split('.') title = splitstr[0] metadata = pd.read_csv(data_dir + '/' + filepath, nrows = 60)
其余同类型文件(如Patient 3-1.csv、Patient 34-1.csv)均可正常读取,但Patient 35-1.csv触发错误,该文件包含度数符号等特殊字符(示例:TOS - R Digit 3 (^13014669E 90° ^13014670E))。
尝试过设置encoding='unicode_escape'、encoding='latin1'及更换engine='python'均无效,最终升级Pandas至2.0.3版本并设置encoding='latin1'解决问题。
问题成因分析
- 文件编码不统一:多数文件采用UTF-8编码,但
Patient 35-1.csv实际是Latin1(ISO-8859-1)编码——字节0xb0在Latin1中对应度数符号°,而UTF-8中该字节不是合法的起始字节,因此触发解码错误。 - 旧版Pandas的编码处理缺陷:旧版Pandas对
latin1编码的读取逻辑存在bug,即使显式指定编码也无法正确解析;更换engine='python'也未解决,因为核心编码处理逻辑的问题未修复。升级至2.0.3版本后,相关bug被修复,latin1编码设置生效。 - 错误编码方案选择:
unicode_escape用于处理字符串中的转义字符(如\uXXXX),而非解析实际文件的字节编码,因此对Latin1编码的文件无效。
编码适配建议
- 批量处理前检测文件编码:使用
chardet或cchardet库检测每个文件的编码,示例代码:import chardet def detect_encoding(file_path): with open(file_path, 'rb') as f: result = chardet.detect(f.read(1000)) # 读取前1000字节检测 return result['encoding'] # 读取文件时使用检测到的编码 encoding = detect_encoding(os.path.join(data_dir, filepath)) metadata = pd.read_csv(os.path.join(data_dir, filepath), encoding=encoding, nrows=60) - 优先使用兼容型编码兜底:若无法确定编码,可先用
latin1读取——它是单字节编码,能兼容所有字节不会触发解码错误,但可能出现乱码,需后续验证数据正确性。 - 保持Pandas版本更新:新版本会修复大量编码相关的bug,尤其是文件读取时的编码解析逻辑,避免因版本缺陷导致的异常。
- 优化文件路径处理:用
os.path.join()代替手动拼接路径,适配不同操作系统的路径分隔符,避免路径错误:metadata = pd.read_csv(os.path.join(data_dir, filepath), nrows=60) - 添加异常捕获逻辑:批量处理时加入异常捕获,对编码错误的文件单独处理,示例:
for filepath in os.listdir(data_dir): file_path = os.path.join(data_dir, filepath) try: metadata = pd.read_csv(file_path, nrows=60) except UnicodeDecodeError: # 尝试用latin1读取或记录异常文件 metadata = pd.read_csv(file_path, encoding='latin1', nrows=60) # 或记录错误文件路径 print(f"编码错误文件:{file_path}")
内容的提问来源于stack exchange,提问作者Rice
相关产品推荐
相关产品推荐

