read_csv 已设 encoding_errors,PyArrow 仍报解码错误
pandas 的 PyArrow CSV 字节输入路径可能没有传递 encoding_errors。先确认真实编码;必须替换坏字节时,选择已核对支持该策略的读取引擎并保留原件。
pd.read_csv(..., engine="pyarrow", encoding="shift_jis", encoding_errors="replace") 仍抛 UnicodeDecodeError,相同字节换 C 引擎却可以读入。应检查错误策略是否真正传到了所选引擎,而不是继续给同一参数换写法。
pandas 3.0.6 的文件字节输入会遇到这个边界:内容含 CP932 中的扩展字符,按 Shift-JIS 解码会失败;PyArrow 路径没有按 encoding_errors="replace" 处理。已解码的文本缓冲区和原始文件、BytesIO 并不是同一入口,前者能读入不能证明后者也采用了相同错误策略。
先确认编码,而不是先接受丢字
CP932 与 Shift-JIS 有重叠,但并非所有字符都相同。文件名写着 Shift-JIS、来自 Windows,都不足以证明实际编码;应核对生成程序的明确设置与原始字节。
若输入已确认是 CP932,应按它的真实编码严格读取,而不是依靠 replace 把合法扩展字符丢成替换符。这个判断与通用的“UTF-8 读 GBK”不同:本题即使明确传了 encoding,错误策略也可能没有进入 PyArrow 的实际解码层。
保留原始文件和完整异常。不要在原件上另存一次“能读的文件”后再开始排查,否则无法确定哪些字符原来存在。
业务明确允许替换时,核对读取引擎
对已经确认需要以替换字符继续解析的文件,可以使用支持该参数的 C 引擎,并保留其余 CSV 规则:
import pandas as pd
frame = pd.read_csv(
"input.csv",
engine="c",
encoding="shift_jis",
encoding_errors="replace",
)
input.csv 是保留原件的读取路径。这里不保证读出的文本等于正确编码下的文本;替换策略本来就会损失无法解码的字符。如果这些字符属于主键、姓名、路径或后续解析语法,应停止该批处理或单独隔离,而不是把“没有异常”作为可用标准。
更换引擎可能影响选项支持、类型推断和性能。核对真实项目的分隔符、引号、缺失值、日期、dtype 与坏行规则,不只替换一个参数便覆盖正式输出。Python 引擎也是另一条路径,应按实际配置验证。
自行用带指定 errors 策略的文本流解码,再交给解析器,属于将解码责任移到应用这一层;应明确文件大小、流生命周期与损失记录,不能同时假设解析器仍在处理原始字节。一般无需为这条错误额外增加复杂包装。
pandas 3.1.0 的 PyArrow 包装路径也没有把该错误策略作为字节解码选项传递。参数出现在调用中,并不保证实际解码已经采用它。验收同时比较原字符、替换位置和记录结构;保留严格解码与允许替换两套预期,避免后续升级悄悄改变数据接受政策。


