2017-09-29 17 views
1

私はAPIからいくつかの母集団データを抽出してcsvに格納する短いpythonスクリプトを書いた。 APIが返すものの例はhereです。 「データ」には8000を超える観測値が含まれているため、効率的なアクセス方法を探しています。私が書いたコードは動作していますが、実行するには数時間かかります。 したがって、私の質問は、このJSONをより効率的にループする方法、またはすべての観測をループせずに必要なデータを抽出する方法はありますか?大規模な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,count\n") 
    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)) 

ありがとうございます。

+0

私のアドバイス:次のうち最も遅いものを見つける:ダウンロードまたは書き込み。しかし、両方の問題に取り組むことができます:1.非同期にダウンロードする2.一度に複数の行を書き込む/出力をバッファする。 – Jakumi

+0

@さくみそれらのどちらも問題ではありません。 –

+0

@StefanPochmannあなたはおそらく正しいです、あなたの答えを読んで、データを見て気にしませんでした。とりわけ第2の 'response.json()'は恐らくキラーです。最初のものはかなり効率的であると仮定します。 – Jakumi

答えて

2

よく、response.json()を何度も何度も何度も何度も呼び出さないでください。代わりに

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

は、全体の事は私のPCに約33秒かかり、この変更後

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

を行います。そして、そのほとんどがリクエストのためのものです。もしあなたがサイトでOKならば、パラレルリクエストを使うことでそれ以上のスピードアップが可能かもしれません。

+0

ありがとう、私は最後の行を追加し、追加のresponse.json()呼び出しを追加して見落としました。それが私の問題を解決しました。 – Bobipuegi

0

データが本当に大きい場合は、データをmongodbにダンプし、効率的に必要なものをクエリします。

1

すでにStefan Pochmannがあなたの質問に回答していますが、自分の問題がどのようになっているかを知ることができました。

標準的なライブラリに含まれているPythonのcProfileなどのプロファイラを使用する方法もあります。あなたのスクリプトがslow_download.pyと呼ばれていると仮定すると、あなたは例えば、range(32, 33)のために、ループ内の範囲を制限し、以下の方法でそれを実行することができ

python3 -m cProfile -s cumtime slow_download.py 

-s cumtime種類の累積時間によって通話。

結果は次のようになります。loads()raw_decode()

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()および関連する方法に関連していることを示唆しています。

+0

ああ、それは素晴らしいです。こちらこそありがとう – Bobipuegi

関連する問題