Python-有效地从大型json文件中查找唯一值

时间:2014-01-05 04:55:48

标签: python json large-files

我有一个大小为150.1MB的json文件 data_large 。文件内的内容属于[{"score": 68},{"score": 78}]类型。我需要找到每个项目的唯一分数列表。

这就是我正在做的事情: -

import ijson  # since json file is large, hence making use of ijson

f = open ('data_large')
content = ijson.items(f, 'item') # json loads quickly here as compared to when json.load(f) is used.
print set(i['score'] for i in content) #this line is actually taking a long time to get processed.

我可以提高print set(i['score'] for i in content)行的效率。目前正在执行 201secs 。可以提高效率吗?

4 个答案:

答案 0 :(得分:2)

这将为您提供一组唯一得分值(仅)作为整数。你需要150 MB的可用内存。它使用re.finditer()进行解析,这比json解析器(在我的计算机上)快三倍。

import re
import time
t = time.time()
obj = re.compile('{.*?: (\d*?)}')
with open('datafile.txt', 'r') as f:
    data = f.read()
s = set(m.group(1) for m in obj.finditer(data))
s = set(map(int, s))
print time.time() - t

使用re.findall()似乎也比json解析器快三倍,它消耗大约260 MB:

import re
obj = re.compile('{.*?: (\d*?)}')
with open('datafile.txt', 'r') as f:
    data = f.read()
s = set(obj.findall(data))

答案 1 :(得分:1)

我认为没有任何方法可以改善事情。缓慢的部分可能只是在某些时候你需要解析整个JSON文件。无论您是预先(json.load)还是一点一点(从ijson.items使用生成器时),都需要最终处理整个文件。

使用ijson的好处是,您只需要在任何给定时间内存少量数据。对于具有一百兆兆字节数据的文件而言,这可能并不重要,但如果您的数据文件增长到千兆字节或更多,这将是一个非常大的问题。当然,这也可能取决于您运行的硬件。如果您的代码将在具有有限RAM的嵌入式系统上运行,则限制内存使用更为重要。另一方面,如果它将在具有大量可用内存的高性能服务器或工作站上运行,则可能没有任何理由可以阻止。

因此,如果您不希望数据过大(相对于系统的RAM容量),您可以尝试测试是否使用json.load在开始时读取整个文件,然后获取set的唯一值更快。我认为还没有其他明显的捷径。

答案 2 :(得分:0)

在我的系统上,下面的简单代码在18秒内处理10,000,000分(139兆字节)。这太慢了吗?

#!/usr/local/cpython-2.7/bin/python

from __future__ import print_function

import json  # since json file is large, hence making use of ijson

with open('data_large', 'r') as file_:
    content = json.load(file_)
    print(set(element['score'] for element in content))

答案 3 :(得分:-2)

尝试使用套装

set([x['score'] for x in scores])

例如

>>> scores = [{"score" : 78}, {"score": 65} , {"score" : 65}]
>>> set([x['score'] for x in scores])
set([65, 78])