我有一个有趣的问题。作为一名初学者,当涉及到数据处理的规模时,我会喜欢这里的老兵的一些技巧。阅读/解析大量JSON.gz文件的优化技巧
我身边有6000
Json.gz文件总数约为5GB压缩和非压缩20GB。 我打开每个文件并使用gzip
模块逐行读取它们;然后使用json.loads()
加载每一行并解析复杂的JSON结构。然后,我会在每次迭代到下一个文件之前将每个文件中的行同时插入到Pytable中。
这一切正在我周围3小时。大容量插入到Pytable并没有真正帮助速度。由于它们有一个真正可怕的结构,大部分时间都没有从解析的JSON行获取值。有些是直接像'attrname':attrvalue
,但有些是复杂和耗时的结构,如:
'attrarray':[{'name':abc, 'value':12},{'value':12},{'name':xyz, 'value':12}...]
...我需要拿起attr
阵列中的所有这些对象已有些相应name
的value
,并忽略那些没有的。所以我需要遍历列表并检查每个JSON对象。 (我会很高兴,如果你能指出任何更快聪明的方法,如果存在的话)
,所以我想它的实际的解析部分没有加速的很大余地。我认为他们的可能是加速范围是实际读取的文件部分。
所以我跑了几个测试(我没有与我的数字现在),甚至删除我的程序的解析部分之后;简单地通过文件行本身花了相当长的时间。
那么请问:是否有这个问题,你觉得我可能是次优做的任何部分?
for filename in filenamelist:
f = gzip.open(filename):
toInsert=[]
for line in f:
parsedline = json.loads(line)
attr1 = parsedline['attr1']
attr2 = parsedline['attr2']
.
.
.
attr10 = parsedline['attr10']
arr = parsedline['attrarray']
for el in arr:
try:
if el['name'] == 'abc':
attrABC = el['value']
elif el['name'] == 'xyz':
attrXYZ = el['value']
.
.
.
except KeyError:
pass
toInsert.append([attr1,attr2,...,attr10,attrABC,attrXYZ...])
table.append(toInsert)
请包含profiler的输出 – shx2 2014-09-10 20:30:24
问题可能是gzip模块。这里有一些替代方法:http://aripollak.com/pythongzipbenchmarks/ – matiasg 2014-09-10 20:46:27
当你说阅读需要相当长的时间时,包括IO和解压缩两项成本。确保你找出哪些需要多少时间。之后,解析和处理这些行是第三件事。他们三个人都可以并行处理,以更好地使用现代计算机。最后,如果你有多行可以解析为JSON,那么整个文件就不是JSON。或者,它可能是文件只包含一行?这可能会影响解析,至少看起来很奇怪。 – 2014-09-10 20:47:57