为何Pandas的utf-8-sig编码可用而Dask读取JSON失败?
问题:Dask读取UTF-8 BOM编码JSON文件失败的原因与解决办法
问题场景
有一个UTF-8 with BOM编码的JSON文件file.json,内容如下:
[{"id":1, "name":"Tim"}, {"id":2, "name":"Jim"}, {"id":3, "name":"Paul"}, {"id":4, "name":"Sam"}]
使用Pandas可成功读取:
df = pd.read_json('file.json', encoding='utf-8-sig', orient='records')
但使用Dask执行相似代码时失败:
df = dd.read_json('file.json', encoding='utf-8-sig', orient='records')
报错信息:
ValueError: An error occurred while calling the read_json method registered to the pandas backend. Original Message: Expected object or value
疑问:这是否是Bug?Dask的编码选项是否与Pandas不一致?
原因分析与解决办法
这并非Dask的Bug,而是两者处理文件编码的逻辑存在差异:
- Pandas的
read_json会直接将encoding='utf-8-sig'传递给文件读取逻辑,自动去除UTF-8 BOM头。 - Dask的
dd.read_json默认按块读取文件,它会先解析文件前几个字节推断JSON格式,而UTF-8 BOM的\xef\xbb\xbf字节序列会干扰这个推断过程,即便指定encoding='utf-8-sig'也无法提前处理BOM头,最终导致解析失败。
可行解决方法
预处理文件去除BOM头
手动或用代码去除文件的UTF-8 BOM头,示例代码:with open('file.json', 'r', encoding='utf-8-sig') as f: content = f.read() with open('file_no_bom.json', 'w', encoding='utf-8') as f: f.write(content)之后用Dask读取处理后的
file_no_bom.json即可正常解析。调整读取块大小(仅适用于小文件)
设置足够大的blocksize让Dask一次性读取整个文件,规避分块读取时的BOM干扰:import os df = dd.read_json('file.json', encoding='utf-8-sig', orient='records', blocksize=os.path.getsize('file.json'))自定义文件读取逻辑传入Dask
先用read_bytes处理编码,再传递给dd.read_json:from dask.bytes import read_bytes import dask.dataframe as dd b_data, _ = read_bytes('file.json', encoding='utf-8-sig') df = dd.read_json(b_data, orient='records')这种方式让Dask读取已去除BOM的字节流,避免格式推断错误。
内容的提问来源于stack exchange,提问作者Guy Altman
相关产品推荐
相关产品推荐

