2016-10-04 9 views
2

私は分析する必要がある多数のJSONファイルがあります。私はiPython(Python 3.5.2 | IPython 5.0.0)を使って、ファイルを辞書に読み込んで、各辞書をリストに追加しています。Pythonで何千ものJSONファイルを読み込むための最も速い方法

私の主なボトルネックはファイルの読み込みです。いくつかのファイルは小さく、素早く読み込まれますが、大きなファイルは私を遅くしています。ここで

は、いくつかのサンプルコードは(申し訳ありませんが、私は実際のデータファイルを提供することはできません)です。

import json 
import glob 

def read_json_files(path_to_file): 
    with open(path_to_file) as p: 
     data = json.load(p) 
     p.close() 
    return data 

def giant_list(json_files): 
    data_list = [] 
    for f in json_files: 
     data_list.append(read_json_files(f)) 
    return data_list 

support_files = glob.glob('/Users/path/to/support_tickets_*.json') 
small_file_test = giant_list(support_files) 

event_files = glob.glob('/Users/path/to/google_analytics_data_*.json') 
large_file_test = giant_list(event_files) 

サポートチケットのサイズが非常に小さいです - 私が見てきた最大のものは6キロバイトです。だから、このコードはかなり速く実行されます。

In [3]: len(support_files) 
Out[3]: 5278 

In [5]: %timeit giant_list(support_files) 
1 loop, best of 3: 557 ms per loop 

しかし、大きなファイルは間違いなく私を遅くしている...これらのイベント・ファイルが到達することができます〜2.5メガバイトごと:

In [7]: len(event_files) # there will be a lot more of these soon :-/ 
Out[7]: 397 

In [8]: %timeit giant_list(event_files) 
1 loop, best of 3: 14.2 s per loop 

私が高速化する方法を研究してきました

In [3]: %timeit giant_list(traffic_files) 
1 loop, best of 3: 16.3 s per loop 

のsimplejsonがはるかに良いしませんでした:this postに出くわしたプロセスまでとUltraJSONを使用した場合、しかし、タイミングがわずかに悪化していた

In [4]: %timeit giant_list(traffic_files) 
1 loop, best of 3: 16.3 s per loop 

このコードを最適化し、多くのJSONファイルをより効率的にPythonに読み込む方法についてのヒントは非常に高く評価されます。

最後に、this postが私の質問に最も近いですが、1つの巨大なJSONファイルを扱っています。

+0

ボトルネックはI/Oであり、解析速度ではありません。より高速なディスクを入手する以外にはあまり行なわれません(あなたはまだSSDで走っていますか?)。 –

+0

Pythonライブラリの 'json'は' simplejson'とまったく同じプロジェクトです。 –

+0

@MartijnPietersどのようにその結論に達しましたか?いくつかの簡単なテストに基づいて、 'json.load()'は高速CPU上で約46MiB/sに達します。これは、ディスクベースのストレージのための手の届かないものではなく、SSDを心配するものではありません。そして、それは彼の入力ファイルがメモリにキャッシュされている可能性を無視しています... – marcelm

答えて

3

リストのリサイズを避けるために、リストの理解を使用してください。

def giant_list(json_files): 
    return [read_json_file(path) for path in json_files] 

あなたが一日の終わりには、単にそれがかつて(withファイルを出た上に自動的にクローズされるだろう)ん、二回

def read_json_file(path_to_file): 
    with open(path_to_file) as p: 
     return json.load(p) 

をファイルオブジェクトをクローズしている、あなたの問題は、I/Oバウンドでありますこれらの変更は少し助けになります。また、私は尋ねる必要があります - あなたは本当に同時にこれらの辞書をすべてメモリに入れなければなりませんか?

+0

良い質問 - 私が同時にメモリに必要としない何千もの小さなファイル。いずれの場合も、〜5つの特定のフィールドが抽出されます。次に、残りの部分を破棄します。大規模なイベントファイルについては、さらに問題があります.Googleアナリティクスのデータであり、解析すると泣かされます:https://developers.google.com/analytics/devguides/reporting/core/v4/migration# parsing_the_v4_response。さらに、私はそれを解析してからPandas DataFrameに変換します。おそらく別の投稿のためにそれを保存するつもりです: -/ – measureallthethings

+0

さらに簡単に:私は 'giant_list()'関数を捨て、リストの理解を直接行います: '[read_json_fileパス) – measureallthethings

関連する問題