值读取大数据集时出错pd.read_json文件

2024-04-20 07:49:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在处理一组使用Yelp reviews datasetcode exercises。在练习的这一点上,我应该读读评论.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)

类型调用返回

^{pr2}$

看起来不错。在

那我试试看

for chunk in review_reader:
    print(chunk)

参考pandas user guide 我得到一个错误:

ValueError: Unexpected character found when decoding 'false'

full error output

更新-有人认为,该问题是由数据文件中嵌入(带引号的)“\n”字符引起的;pandas认为JSON记录不是每行一个,而是多行。在

如果是这样的话,错误消息是非常不透明的。另外,对于600万行,我应该如何告诉pd.read_json忽略{}而只查看数据中的实际换行?在

更新

有人建议,如果我修复我的错别字(这篇文章中的错别字,不是我代码中的错别字),并使用Unix文件路径而不是URL(JSON不在乎:请参阅docs)。在

当我这样做但保留StringIO()时,会得到一个不同的ValueError。在

当我这样做但删除StringIO()时,代码就可以工作了。在

这看起来很脆弱。:-(


注意本教程有一个答案键。我已经试过了。答案键使用

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

这会引发打字错误

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"}


Tags: 文件to数据代码jsonpandasread记录
1条回答
网友
1楼 · 发布于 2024-04-20 07:49:35

首先,你的

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

不是有效的python代码。如果您试图这样执行,您将得到一个无效的语法错误。我假设这只是显示路径变量的值。我不知道这些省略号是文字还是您的环境截断path显示的结果。在这里,我假设您的路径是系统的有效文件URL,因为在这里考虑不正确的路径似乎没有关系。在

不管怎样,read_json可以从指定的文件URL中读取json(我在那里学到了一些东西),如果您一次性地读取它:

^{pr2}$

但是如果您试图从中创建一个读卡器

^{3}$

然后你得到

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

第二,是的,用StringIO包装类似于文件的参数可以避免这个错误,但是出于任何您可能认为的原因,它的使用是基于对您所指的pandas文档的误读。在

我将引用read_json文档中的几位:

Signature: pd.read_json( path_or_buf=None, ...

path_or_buf : a valid JSON string or file-like, default: None The string could be a URL. Valid URL schemes include http, ftp, s3, gcs, and file. For file URLs, a host is expected. For instance, a local file could be 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()就是这样做的。因此,当您在StringIO()中包装描述您的文件URL的字符串时,我希望read_json会尝试将该字符串解释为从文件中读取并解析的JSON。它的失败是可以理解的,因为它不是JSON。在

这让我们回到了read_json不能成批读取文件URL的原因。我现在还没有一个好的答案。{2>这个函数的内部结构是如何打开的。如果您有意或被迫从一个文件URL中进行这种分块,那么我怀疑您可能正在寻找控制文件打开的模式,或者可能以某种方式为read_json如何解释它获得的bytestream提供明确的指导。像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不使用正斜杠路径分隔符,通过以上述方式连接字符串来构造路径可能很脆弱,但通常如果您使用“正确的”正斜杠分隔符(smile),体面的语言可以在内部理解这一点。它使用反斜杠构建路径,这肯定会让你痛苦。但你要注意。在

相关问题 更多 >