使用Python的Polars读取csv.xz文件报错:invalid utf-8 sequence
诊断与修复Polars读取xz压缩CSV的UTF-8错误
问题原因分析
直接使用pl.read_csv('myfile.csv.xz')报错,而解压后或通过lzma.open读取正常,核心原因可能是:
- Polars内置的xz解压逻辑对字节流的UTF-8校验比Python标准库的
lzma模块更严格,哪怕是ASCII编码的文件,若存在个别边缘字节(比如文件末尾的冗余字节),会触发校验失败。 lzma.open在文本模式下默认使用系统本地编码(如Latin-1),会将所有字节视为合法字符,而Polars默认严格按UTF-8解析,导致冲突。
诊断步骤
- 定位无效字节位置:运行以下脚本,找出文件中不符合UTF-8规范的字节:
import lzma with lzma.open('myfile.csv.xz', 'rb') as f: content = f.read() try: content.decode('utf-8') except UnicodeDecodeError as e: print(f"无效字节位置: {e.start},字节值: {hex(content[e.start])}") print(f"上下文内容: {content[e.start-20:e.start+20]}")
- 对比编码处理差异:检查
lzma.open的默认编码,执行import locale; print(locale.getpreferredencoding(False)),确认是否为Latin-1或其他非UTF-8编码。
修复方案
方案1:显式指定宽松编码
Polars读取时指定encoding='latin-1',该编码兼容ASCII且接受所有字节,不会触发UTF-8校验错误:
import polars as pl df = pl.read_csv('myfile.csv.xz', encoding='latin-1')
验证数据正常后,可根据实际需求再转换编码。
方案2:沿用lzma.open读取方式
继续使用Python标准库的lzma模块打开文件,Polars可直接读取该文件对象,大文件也能流式处理:
import polars as pl import lzma with lzma.open('myfile.csv.xz', 'rt') as f: df = pl.read_csv(f)
方案3:预解压后读取(适合小文件)
若文件体积不大,可先解压再读取:
xz -d myfile.csv.xz
然后执行:
import polars as pl df = pl.read_csv('myfile.csv')
内容的提问来源于stack exchange,提问作者Vladimir Kirilin
相关产品推荐
相关产品推荐

