使用JSON对象解析和处理大型文件的更有效方法

时间:2014-07-10 21:42:05

标签: python json pandas bigdata

如何优化以下代码?(并且Python可以用于此,还是应该使用其他工具?)

这是迄今为止我所提出的最疯狂的问题,但是我打算给它一个机会,希望能得到一些关于我是否正在利用正确的工具和方法来有效处理大量数据的建议。我不一定在寻找优化我的代码的帮助,除非有一些我完全忽略的东西,但基本上只是想知道我是否应该使用不同的框架而不是Python。我对Python不够新,不能完全确定是否可以更有效地处理大量数据并存储到数据库中。

下面的实现读取目录中的文本文件:

  • 每个文本文件包含50K行JSON对象......
  • 需要先解析并读取,然后在加载到数据库之前转换为CSV格式。
  • 我讨厌使用列表容器,我希望我能用Python研究实现其他更好的方法。我最初的想法是我应该使用发电机但不完全确定。
  • 最后的疯狂连接部分很重要,因为它将逗号分隔的列表转换为自己的行。 Converting Column with string separated values into rows

代码:

  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 个答案:

答案 0 :(得分:3)

首先,对于json来说, lines 并不是特别有用的指标! 其次,你有正确的想法:你肯定想做这个基于块的(分别读取/清理/转储每个部分)。

我建议使用pandas'read_json函数,它在创建DataFrames方面效率更高(它不会创建临时python dict),请参阅reading in json section of the docs < / p>

  • 如果没有实际上 json,那么进行字符串操作以使它们成为json通常是你最好的选择。*
  • 如果您有“奇怪形状”的json,那么您可以在阅读时json_normalize,或者在读取DataFrame后解析包含多列的列(例如,使用Series字符串方法或应用)。 / LI>

*目前还不清楚实际的格式是什么,但通常不需要将它们变成有效 json。

Python奖金提示:如果你更多的是一些缩进级别深入考虑将其分解为更多功能。 (这里显而易见的选择是f1(logfile)f2(line),但使用描述性名称......)