You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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'解决问题。

问题成因分析
  1. 文件编码不统一:多数文件采用UTF-8编码,但Patient 35-1.csv实际是Latin1(ISO-8859-1)编码——字节0xb0在Latin1中对应度数符号°,而UTF-8中该字节不是合法的起始字节,因此触发解码错误。
  2. 旧版Pandas的编码处理缺陷:旧版Pandas对latin1编码的读取逻辑存在bug,即使显式指定编码也无法正确解析;更换engine='python'也未解决,因为核心编码处理逻辑的问题未修复。升级至2.0.3版本后,相关bug被修复,latin1编码设置生效。
  3. 错误编码方案选择: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:05:07