有没有一种高效,快速的方式来加载python中的大json文件?

我有一些500MB的JSON文件。 如果我使用“简单的”json.load一次加载它的内容,将消耗大量的内存。

有没有办法部分读取文件? 如果这是一个文本,行分隔文件,我将能够遍历行。 我正在寻找比喻。

有什么build议么? 谢谢

简短的回答:不。

正确地分割一个json文件需要知道json对象图的正确性。

然而,如果你有这方面的知识,那么你可以实现一个类似于文件的对象,它包装了json文件并吐出适当的块。

例如,如果你知道你的json文件是一个单一的对象数组,你可以创build一个包装json文件并返回数组块的生成器。

你将不得不做一些string内容parsing来获得json文件的权利。

我不知道是什么产生你的JSON内容。 如果可能的话,我会考虑生成一些可pipe理的文件,而不是一个巨大的文件。

这个问题有一个重复有更好的答案。 请参阅https://stackoverflow.com/a/10382359/1623645 ,其中build议ijson 。

更新:

我试了一下,而ijson是JSON SAX是什么XML。 例如,你可以这样做:

import ijson for prefix, the_type, value in ijson.parse(open(json_file_name)): print prefix, the_type, value 

prefix是JSON树中的点分隔索引(如果您的键名称中有点,会发生什么情况?我想这也会对JavaScript不利),该types描述了一个SAX类事件, 'null', 'boolean', 'number', 'string', 'map_key', 'start_map', 'end_map', 'start_array', 'end_array'value是对象的值或None如果the_type是一个事件像开始/结束一个地图/数组。

该项目有一些文件,但没有足够的全球文件。 我不得不深入ijson/common.pyfind我正在寻找的东西。

所以问题不是每个文件都太大,而是太多了,而且他们似乎正在增加内存。 Python的垃圾收集器应该没问题,除非你保持你不需要的引用。 没有任何进一步的信息很难确切地知道发生了什么,但有些事情可以尝试:

  1. 模块化您的代码。 做类似的事情:

     for json_file in list_of_files: process_file(json_file) 

    如果以不依赖任何全局状态的方式编写process_file() ,并且不改变任何全局状态,那么垃圾回收器应该能够完成它的工作。

  2. 在单独的进程中处理每个文件。 不要一次parsing所有的JSON文件,编写一个程序parsing一个,并从shell脚本或从另一个通过subprocess.Popen调用脚本的python进程传递每个。 这有点不那么优雅,但是如果没有其他的工作,它将确保你不要把从一个文件到下一个陈旧的数据。

希望这可以帮助。

是。

你可以使用我写的jsonstreamer类 SAXparsing器,它允许你parsing任意大小的块,你可以在这里得到它,并检出README的例子。 它的速度很快,因为它使用'C'yajl库。

在你提到内存不足时,我必须质疑你是否真的在pipe理内存。 在尝试读取新对象之前,是否使用“del”关键字来删除旧对象? 如果删除它,Python永远不应该在内存中保留一些东西。

另一个想法是尝试将其加载到像MongoDB这样的文档存储数据库中。 它很好地处理了大量的JSON。 尽pipe您可能会遇到同样的问题加载JSON – 避免一次加载文件的问题。

如果path适合您,那么您可以通过客户端与JSON数据进行交互,并且可能不必将整个blob存储在内存中

http://www.mongodb.org/

除了@codeape

我会尝试编写一个自定义的jsonparsing器来帮助你找出你正在处理的JSON blob的结构。 只打印键名等。制作一个分层树,并决定(你自己)如何分块。 这样你就可以做@codeapebuild议的 – 将文件分割成更小的块等等

“垃圾收集器应该释放内存”

正确。

既然没有,那么别的是错的。 一般来说,无限记忆增长的问题是全局variables。

删除所有全局variables。

将所有模块级代码变成更小的函数。