ValueError使用pd.read_json读取大数据集

时间:2019-06-23 21:00:36

标签: python json pandas valueerror

我正在使用code exercises的一组Yelp reviews dataset。现在,在练习中,我应该读入review.json,每行有一个JSON记录。我制作了一个较小版本的JSON文件,仅进行100条记录用于测试。

我可以将整个测试文件读入pandas数据框中并进行检查。

但是,完整的数据集文件大约有600万行。建议使用chunksize并构建一个json阅读器。即使使用测试输入,我也会遇到错误。

我的代码当前看起来像这样

path = 'file://localhost/Users/.../DSC_Intro/'
filename = path + 'yelp_dataset/review_100.json'

# create a reader to read in chunks
review_reader = 
pd.read_json(StringIO(filename), lines=True, chunksize=10)

type(review_reader)

类型调用返回

pandas.io.json.json.JsonReader

看起来不错。

然后我尝试

for chunk in review_reader:
    print(chunk)
pandas user guide中引用的

我得到一个错误:

ValueError: Unexpected character found when decoding 'false'

full error output

更新-已建议该问题是由数据文件中嵌入(引号)“ \ n”字符引起的;大熊猫看到的JSON记录不是每行一条,而是多行。

这种情况下,错误消息非常不透明。另外,如果有600万行,我该如何告诉pd.read_json忽略"\n"而仅查看数据中的实际换行符?

更新

建议如果我修复我的错字(本文中是错字,而不是我的代码中的错字),并使用Unix文件路径而不是URL(JSON无关紧要:请参阅文档)。 / p>

当我这样做但保留StringIO()时,我得到了另一个ValueError。

当我这样做但删除StringIO()时,代码将起作用。

这似乎非常脆弱。 :-(


注意。本教程具有答案键。我已经尝试过该代码。答案键使用

review_reader = 
pd.read_json(filename, lines=True, chunksize=10)

会引发TypeError

sequence item 0: expected str instance, bytes found

添加StringIO()似乎已经解决了这个问题。

输入样本JSON记录,每行输入文件一个。

{"review_id":"Amo5gZBvCuPc_tZNpHwtsA","user_id":"DzZ7piLBF-WsJxqosfJgtA","business_id":"qx6WhZ42eDKmBchZDax4dQ","stars":5.0,"useful":1,"funny":0,"cool":0,"text":"Our family LOVES the food here. Quick, friendly, delicious, and a great restaurant to take kids to. 5 stars!","date":"2017-03-27 01:14:37"}

1 个答案:

答案 0 :(得分:0)

首先,您的

path 'file://localhost/Users/.../DSC_Intro/'

无效的python代码。如果尝试以这种方式执行该操作,则会收到无效的语法错误。那么,我假设这只是显示path变量的值。我不知道这些省略号是文字上的,还是您的环境截断path的显示结果。我在这里假设您的路径是系统的有效文件URL,因为在这里考虑错误的路径似乎并不重要。

无论哪种方式,是的,read_json可以一口气读取文件URL,就像您在其中指定的那样(我在那里学到了东西),它可以从文件URL中读取json:

pd.read_json(fname, lines=True)

但是,如果您尝试通过指定此内容来创建阅读器,则

pd.read_json(fname, lines=True, chunksize=...)

那么你就得到

TypeError: sequence item 0: expected str instance, bytes found

第二,是的,用StringIO包装类似文件的参数可以使该错误消失,但是由于您可能认为的任何原因都无法解决问题,它的使用是基于对您指向的熊猫文档的误读。 / p>

我将在此处引用read_json文档中的一些内容:

  

签名:pd.read_json(       path_or_buf =无,...

     

path_or_buf:有效的JSON字符串或类似文件的默认值:无       该字符串可以是URL。有效的URL方案包括http,ftp,s3,       gcs和文件。对于文件URL,需要一个主机。例如,本地       文件可以是file://localhost/path/to/table.json

因此,使用read_json,您可以为它提供一个有效JSON的实际字符串,也可以为它提供一个类似于文件的对象,该对象指向包含JSON的文件。

您引用的熊猫文档中的通知:

In [258]: jsonl = '''
   .....:     {"a": 1, "b": 2}
   .....:     {"a": 3, "b": 4}
   .....: '''
   .....: 

是JSON,不是路径。当他们的示例这样做时:

df = pd.read_json(jsonl, lines=True)

它只是解析字符串中的JSON-此处不涉及任何文件。 然后,当它想演示从文件中读取文件时,便会这样做

# reader is an iterator that returns `chunksize` lines each iteration
In [262]: reader = pd.read_json(StringIO(jsonl), lines=True, chunksize=1)

换句话说,它们通过StringIO()包装JSON字符串,而不是路径。这只是出于记录示例的目的,因此您可以看到如果您将JSON字符串当作从文件中读取一样对待,则可以成批读取。那就是StringIO()所做的。因此,当您将描述文件URL的字符串包装在StringIO()中时,我希望read_json然后尝试将该字符串解释为正在从文件读取的JSON并进行解析。可以理解,它不是JSON,因此会失败。

这使我们回到为什么read_json无法分块读取文件URL的原因。我对此没有立即好的答案。我怀疑这取决于read_json如何打开文件URL的内部结构,或者它是基于什么功能。如果您打算或被迫从文件URL进行分块,那么我怀疑您是在控制打开文件的模式,或者也许以某种方式为read_json提供了明确的指导解释它得到的字节流。我不确定urllib2之类的库在这里可能有用。

但是,让我们在此处进行最佳修复。为什么我们尝试将路径指定为文件URL?只需将您的路径指定为操作系统路径,例如

path = '/path/to/my/data/'

然后

filename = path + 'yelp_dataset/review_100.json'

# create a reader to read in chunks
review_reader = pd.read_json(filename, lines=True, chunksize=10)

我敢打赌,它按预期工作! (它对我来说一如既往)。 注意:Windows不使用正斜杠路径定界符,以上述方式通过串联字符串构造路径可能很脆弱,但是通常如果使用“适当的”正斜杠定界符(微笑),那么体面的语言就会内部理解这一点。它使用反斜杠构造路径,这肯定会引起您的痛苦。但是请注意这一点。