更高效的解析和处理大文件的JSON对象的方法
下面的代码怎么优化?(用Python可以吗,还是应该换个工具?)
这是我在Stack Overflow上问过的最疯狂的问题,但我想试试,希望能得到一些建议,看看我是否在用正确的工具和方法来高效处理大量数据。我并不一定在寻找代码优化的帮助,除非我完全忽略了什么,但我主要想知道是否应该完全换个框架,而不是继续用Python。我对Python还不够熟悉,不太确定是否能更高效地处理大量数据并存储到数据库中。
下面的实现代码是用来读取一个目录中的文本文件:
- 每个文本文件里有5万行的JSON对象……
- 这些对象需要被解析、读取,然后转换成CSV格式,最后再加载到数据库中。
- 我不喜欢使用列表容器,希望能找到其他方法在Python中实现这个功能,做得更好。我最初的想法是应该使用生成器,但还不太确定。
- 最后的那个疯狂的连接部分很重要,因为它把用逗号分隔的列表转换成了自己的行。 将用字符串分隔的列转换为行
代码:
triggerZipFiles = glob.glob('*.zip')
for triggerFiles in triggerZipFiles:
with zipfile.ZipFile(triggerFiles, 'r') as myzip:
for logfile in myzip.namelist():
datacc = []
zipcc = []
csvout = '{}_US.csv'.format(logfile[:-4])
f = myzip.open(logfile)
contents = f.readlines()
for line in contents:
try:
parsed = json.loads(line[:-2])
if "CC" in parsed['data']['weatherType'] and "US" in parsed['zipcodes']:
datacc.append(parsed['data'])
zipcc.append(parsed['zipcodes'])
except:
pass
if len(datacc) > 0:
df = pd.concat([pd.DataFrame(zipcc), pd.DataFrame(datacc)], axis=1)
df = pd.concat((pd.Series((v, row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key'], row['key'], row['key'],
row['key'], row['key'], row['key'], row['key']), df.columns) for _,
row in df.iterrows() for v in row['US']), axis=1).T
df.to_csv(csvout, header=None, index=False)
else:
pass
print datetime.now().strftime('%Y/%m/%d %H:%M:%S') + ": Finished: {}".format(logfile)
1 个回答
3
首先,行数在处理json时并不是一个特别有用的指标!
其次,你的想法是对的:确实应该分块处理(分别读取、清理和保存每一部分)。
我建议使用pandas的read_json
函数,这样在创建数据框时效率更高(它不会创建一个临时的python字典),可以参考文档中的读取json部分。
- 如果它们实际上并不是真正的json,那么通过字符串处理把它们变成json通常是最好的办法。
- 如果你有“形状奇怪”的json,那么在读取时可以使用
json_normalize
,或者在读取数据框后解析那些包含多个列的列(比如使用Series的字符串方法或apply)。
*实际格式不太清楚,但通常只需稍微处理一下就能变成有效的json。
Python小贴士:如果你的缩进层级超过几层,考虑把它拆分成更多的函数。(这里显而易见的选择是有f1(logfile)
和f2(line)
,但使用描述性的名称会更好...)