在 Pandas UnicodeDecodeError 中无法使用 pandas.read_json() 解码 JSON 文件中的 Unicode Ascii

Posted

技术标签:

【中文标题】在 Pandas UnicodeDecodeError 中无法使用 pandas.read_json() 解码 JSON 文件中的 Unicode Ascii【英文标题】:In Pandas UnicodeDecodeError Cannot decode Unicode Ascii in JSON file using pandas.read_json() 【发布时间】:2017-08-03 09:43:02 【问题描述】:

提前感谢您的帮助。我正在尝试将 JSON 文件读入 pandas DataFrane 并获得大量 unicode/ascii 错误。 编辑:错误似乎在于 JSON 文件是多行的,每行都有自己的 JSON 对象。

使用如下所示的数据文件:

"data.json" = 

"_i":"$o":"5b","c_id":"10","p_id":"10","c_c":2,"l_c":59,"u":"n":"J","id":"1","c_t":"2010","m":"Hopefully \n\nEDIT: Actually."
"_i":"$o":"5b","p_id":"10","c_id":"10","p_id":"10","c_c":0,"l_c":8,"u":"n":"S","id":"1","c_t":"2010","m":"in-laws?"

编辑:回应评论,上面不是要运行的代码,它作为我的数据文件的示例包含在内,保存为json文件。

由于这是一个多行文件,因此我尝试使用此链接Loading a file with more than one line of JSON into Python's Pandas

import pandas
df = pandas.read_json('data.json', lines = True)

给出错误:

    json = u'[' + u','.join(lines) + u']'
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 436: ordinal not in range(128)

根据 GitHub https://github.com/pandas-dev/pandas/issues/15132 上突出显示的这个问题,这是因为:

如果默认编码设置为 ascii(检查 sys.getdefaultencoding()),这可能在 Python 2.7 中发生。当lines=True 时,StringIO 会将输入字符串转换为ascii,由于混合了utf-8 和ascii 字符串而导致UnicodeDecodeError。

他们的解决方案是将系统编码从 ascii 更改为 utf-8,但是,我知道这是不可取的 - 来源:Changing default encoding of Python?。

我还尝试在read_json() 中将编码都更改为utf-8 / ascii,但无济于事。

我怎样才能成功地将这个json文件读入pandas DataFrame,同时保留多行结构?

非常感谢!

【问题讨论】:

如果没有 Minimal, Complete, and Verifiable 示例,这将很难有人帮助您。 @StephenRauch 感谢您的评论。我以为我已经提供了 - 我提供了源代码、数据文件、我期望的结果以及我得到的结果。你还想看什么? (这是一个真正的问题,不是讽刺) 根本问题是这里没有任何东西可以剪切和粘贴来运行。第一个代码块是语法错误。很多人不会再读下去了。 感谢您的评论。所以第一个代码块提供了一个数据样本——我认为"With a data file that looks like:"显然不是。显然,无法将其作为 Json 文件复制和传递。而是提供它,以便如果有人想测试我的代码,他们将能够保存这些数据并重现我的错误。显然我没有说得足够清楚,应该更冗长 - 我已将这些信息编辑到问题中。感谢您的建议。 问题不在于缺少信息。获取这些信息并尝试查看是否有人可以帮助您是困难的。也许这将有助于理解这个问题:codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question 【参考方案1】:

人们有时在这里很暴躁。好的,所以在 python 2.7 中,它默认为 ascii,您可以使用以下行来查看:

encoding = sys.getdefaultencoding()
print encoding

似乎他们在 pandas 中解决了这个问题,允许您设置如下编码:

pd.read_json(the_file, encoding = encoding)

不幸的是,这条线似乎也不起作用。

因此,我们也可以自己做,而不是依赖 pandas。所有“行”选项的作用是在末尾添加方括号并用逗号连接(即 [,,] )。

首先,读入数据并剥离:

with open(path+theFile, 'rb') as f:
    data = f.readlines()

data = map(lambda x: x.rstrip(), data)

Python 读取的行编码没有问题。然后我们可以使用来自 pandas 的相同代码来执行这些行:

data_lines = "[" + ','.join(data) + "]"

然后像往常一样将这些行读入解析器:

df = pd.read_json(data_lines)

顺便说一句,这在 python 3 中都不是问题

【讨论】:

对此回复延迟表示歉意。虽然我当时解决了这个问题(请参阅我发布的答案),但我已经通过并检查了您的解决方案与我的解决方案。它是最优秀的——而我的将所有内容都保存为 unicode,而您的答案具有保留原始数据类型的效果。这很重要,因为我有很多 datetime timestamp 信息。虽然您的答案需要稍长一些(0.45 秒对 0.35 秒),但我相信这不会影响数据类型的好处。基本上你的答案很好用!非常感谢您花时间写它 - 我真的很感激! :)【参考方案2】:

最后,我最终在这里使用https://***.com/a/34463368/2254228 的答案,利用json.loads() 逐行保存文件的输出。

我的代码就这样变成了:

import pandas
import json

data=[]
with open('data.json') as f:
    for line in f:
        data.append(json.loads(line))
df = pd.DataFrame(data)

【讨论】:

以上是关于在 Pandas UnicodeDecodeError 中无法使用 pandas.read_json() 解码 JSON 文件中的 Unicode Ascii的主要内容,如果未能解决你的问题,请参考以下文章

pandas 对比两个列表

Pandas基础教程

Pandas:如何将 cProfile 输出存储在 pandas DataFrame 中?

pandas 是不是读取完整的数据文件并将其存储在数据框中?在 pandas 中加载 100mb 文件是不是有效?

检查列中是不是存在值并根据不同条件在另一个 Pandas 中更改:Pandas

pandas 如何对比判断数据是不是在excel表格中?