在Python中读取数千个JSON文件的最快方法

在Python中读取数千个JSON文件的最快方法,python,json,python-3.x,ipython,Python,Json,Python 3.x,Ipython,我有很多JSON文件需要分析。我正在使用iPython(python3.5.2 | ipython5.0.0),将文件读入字典,并将每个字典附加到列表中 我的主要瓶颈是读取文件。有些文件较小,读取速度较快,但较大的文件使我的速度变慢 下面是一些示例代码(抱歉,我无法提供实际的数据文件): 支持票证的大小非常小——我见过的最大票证是6KB。因此,这段代码运行得非常快: In [3]: len(support_files) Out[3]: 5278 In [5]: %timeit giant_li

我有很多JSON文件需要分析。我正在使用iPython(
python3.5.2 | ipython5.0.0
),将文件读入字典,并将每个字典附加到列表中

我的主要瓶颈是读取文件。有些文件较小,读取速度较快,但较大的文件使我的速度变慢

下面是一些示例代码(抱歉,我无法提供实际的数据文件):

支持票证的大小非常小——我见过的最大票证是6KB。因此,这段代码运行得非常快:

In [3]: len(support_files)
Out[3]: 5278

In [5]: %timeit giant_list(support_files)
1 loop, best of 3: 557 ms per loop
但更大的文件肯定会让我慢下来……这些事件文件每个都可以达到~2.5MB:

In [7]: len(event_files) # there will be a lot more of these soon :-/
Out[7]: 397

In [8]: %timeit giant_list(event_files)
1 loop, best of 3: 14.2 s per loop
我曾研究过如何加快这一过程,但在使用UltraJSON时,遇到了时间稍差的问题:

In [3]: %timeit giant_list(traffic_files)
1 loop, best of 3: 16.3 s per loop
SimpleJSON没有做得更好:

In [4]: %timeit giant_list(traffic_files)
1 loop, best of 3: 16.3 s per loop
任何关于如何优化此代码并更有效地将大量JSON文件读入Python的提示都是非常值得赞赏的


最后,它是我发现的最接近我的问题的文件,但处理的是一个巨大的JSON文件,而不是许多较小的文件。

使用列表理解来避免多次调整列表大小

def giant_list(json_files):
    return [read_json_file(path) for path in json_files]
您要关闭文件对象两次,只需关闭一次(使用退出
时,
文件将自动关闭)


归根结底,您的问题是I/O受限的,但是这些更改会有所帮助。另外,我必须问一下——您真的必须同时在内存中存储所有这些词典吗?

您的瓶颈是I/O,而不是解析速度。除了获得更快的磁盘(您在SSD上运行了吗?)之外,没什么需要做的。Python库中的
json
simplejson
@MartijnPieters是如何得出这个结论的?根据一些快速测试,
json.load()
在快速CPU上达到大约46MiB/s。这对于基于磁盘的存储来说并非遥不可及,更不用说SSD了。这忽略了他的输入文件被缓存在内存中的可能性…@measureallethings加载这些json文件目前需要多长时间?请注意,您正在尝试读取和解析大约1.2GB的数据。还要注意,这些json实体最终可能会使用更多的内存作为Python对象。整数
5
在json中需要一个字节,但作为Python对象可能需要16个字节。好问题——我不需要同时在内存中存储数千个较小的文件。在每种情况下,我都要提取5个特定字段,然后丢弃字典的其余部分。当涉及到更大的事件文件时,我遇到了更多的问题…这是谷歌分析数据和解析它让我哭泣:。此外,我解析它,然后将其转换为Pandas数据帧…可能会将其保存到另一篇文章中:-/更简单:我放弃了
giant_list()
函数,直接进行列表理解:
[读取事件_文件中的路径的json_文件(路径)]
这本词典会成为这里的瓶颈吗?还是你提到它是因为它的格式不好?
def giant_list(json_files):
    return [read_json_file(path) for path in json_files]
def read_json_file(path_to_file):
    with open(path_to_file) as p:
        return json.load(p)