通过大型JSON文件有效循环



我编写了一个简短的Python脚本,以从API中提取一些人群数据并将其存储到CSV中。可以在此处找到API返回的示例。"数据"包含8000多个观测值,因此我正在寻找一种访问它的有效方法。我编写的代码正在工作,但需要几个小时才能运行。因此,我的问题是,是否有任何方法可以更有效地循环浏览此JSON,或者可以提取所需的数据而不循环遍历每个观察?

import requests 
api_base = "http://dw.euro.who.int/api/v3/data_sets/HFAMDB/HFAMDB_8"
with open("population.csv", "w") as outfile:
   outfile.write("country,year,group,fullname,countn")
   for i in range(32,51):
      response = requests.get(api_base+str(i))
      print(api_base+str(i))
      for observation in response.json()['data']:
          count = observation["value"]["numeric"]
          country = observation["dimensions"]["COUNTRY"]
          year = observation["dimensions"]["YEAR"]
          group = observation["dimensions"]["AGE_GRP_6"]
          fullGroupName = response.json()['full_name']
          if observation["dimensions"]["SEX"] == "ALL":
              outfile.write("{},{},{},{},{}n".format(country, year, group, fullGroupName, count))

预先感谢您的答案。

好吧,请不要一遍又一遍地不必要地致电response.json()

而不是

  for observation in response.json()['data']:
      fullGroupName = response.json()['full_name']

  data = response.json()
  for observation in data['data']:
      fullGroupName = data['full_name']

改变了整个过程,将我的电脑带走了大约33秒。几乎所有这些都是为了要求。也许您可以通过使用并行请求进一步加快该网站的速度。

尽管Stefan Pochmann已经回答了您的问题,但我认为值得一提的是您如何弄清楚自己的问题。

一种方法是使用profiler,例如Python的Cprofile,其中包含在标准库中。

假设您的脚本称为slow_download.py,您可以将循环中的范围限制为例如range(32, 33)并以以下方式执行:

python3 -m cProfile -s cumtime slow_download.py

-s cumtime按累积时间对呼叫进行分类。

结果是:

   http://dw.euro.who.int/api/v3/data_sets/HFAMDB/HFAMDB_832
          222056 function calls (219492 primitive calls) in 395.444 seconds
   Ordered by: cumulative time
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    122/1    0.005    0.000  395.444  395.444 {built-in method builtins.exec}
        1   49.771   49.771  395.444  395.444 py2.py:1(<module>)
     9010    0.111    0.000  343.904    0.038 models.py:782(json)
     9010    0.078    0.000  332.900    0.037 __init__.py:271(loads)
     9010    0.091    0.000  332.801    0.037 decoder.py:334(decode)
     9010  332.607    0.037  332.607    0.037 decoder.py:345(raw_decode)
     ...

这清楚地表明该问题与json()和相关方法有关:loads()raw_decode()

如果数据真的很大,请将数据转储到mongodb中,并有效地查询任何您想要的内容。

最新更新