2017-01-06 7 views
1

私はPythonには新しく、dictファイルから特定の情報を抽出しています。複雑なJSONファイルから情報を抽出する最も効率的な方法は何ですか?

テキストデータを格納する数百万のJSONファイルがあります。すべてのJSONファイルは同様の構造を持っています。構造的には多くのバリエーションがあります。各JSONファイルについて、特定のキーからすべてのテキスト文字列を抽出し、それらをdictとして格納する必要があります。

json1およびjson2は、以下の簡単な例です。私が行ってきたことは、JSONファイルからサンプルを取り出し、解析し、可能なバリエーションをすべて含むようにif文をたくさん書くことです。しかし、私はそれが非効率的であると思って、まだすべてのシナリオを含めることができません。キー"text"を使用して値を検索し抽出する一般的な方法があるのだろうかと思います。

json1 = { 
     "section": { 
        "heading":{"lvl":"A1", "text":"today"}, 
        "paragraph":[ 
           {"color":"green", "text":"yesterday"}, 
           {"color":"purple", "text":"tomorrow"} 
           ] 
        } 
     } 

json2 = { 
     "paragraph":{"text":"everyday", "color": "black"} 
     } 

つまり、「テキスト」のキーを含むすべてのテキスト文字列を含むdictを取得したいとします。 json1については、{"json1":"today yesterday tomorrow"}を取得したいと考えています。 json2については、{"json2":"everyday"}を取得したいと考えています。

ご協力いただきまして誠にありがとうございます。

+0

あなたは結果として 'set'または' dict'をしたいですか?あなたは 'set'を見せました。 –

+0

@ juanpa.arrivillaga結果として「dict」が欲しいです。私は私の説明を修正しました。混乱させて申し訳ありません。 –

+1

これで、jsonオブジェクトの名前をキー(奇妙なもの)とし、文字列をコンマで連結した文字列で構成した 'dict'を手に入れました。これは、特にキーと値のペアが1つの辞書なので、特に便利です。 –

答えて

5

あなたが他の何かを知らず、構造があなたが示唆するようにむしろ任意である可能性がある場合は、すべてのノードにアクセスして確認する必要があります。これは、再帰を使用して一般的な方法で実現できます。ここではそれを達成するための間に合わせと機能は次のとおりです。ここで

In [4]: def extract_text(obj, acc): 
    ...:  if isinstance(obj, dict): 
    ...:   for k, v in obj.items(): 
    ...:    if isinstance(v, (dict, list)): 
    ...:     extract_text(v, acc) 
    ...:    elif k == "text": 
    ...:     acc.append(v) 
    ...:  elif isinstance(obj, list): 
    ...:   for item in obj: 
    ...:    extract_text(item, acc) 
...:  

は、あなたがそれを使用する方法である:

In [5]: acc1 = [] 

In [6]: extract_text(json1, acc1) 

In [7]: acc1 
Out[7]: ['yesterday', 'tomorrow', 'today'] 

In [8]: acc2 = [] 

In [9]: extract_text(json2, acc2) 

In [10]: acc2 
Out[10]: ['everyday'] 

注意、あなたの質問は本当に、JSONとは何の関係もありません。これはテキストベースのデータ直列化フォーマットです。あなたはすでにデシリアライズされたデータとPythonのデータ構造を扱っています。あなたが本当にあなたの質問を持っている結果をしたい場合はいずれにせよ、あなたは簡単に行うことができます。

In [11]: {"json1": ",".join(acc1)} 
Out[11]: {'json1': 'yesterday,tomorrow,today'} 

または任意のセパレータは、単純な宇宙のように、上に参加することを好む:

In [12]: {"json1": " ".join(acc1)} 
Out[12]: {'json1': 'yesterday tomorrow today'} 
0

場合あなたはjsonファイルの構造について何も知らないので、私はコンテンツをダンプしてリストに検索することをお勧めします。迅速な解決策は次のとおりです。 'text'のキーが1語のエントリに対応していることを前提にしています。 JSONファイルあたり

import pickle 
import json 

# Open .json file 
f = open("myjson.json") 
# Load the content 
info = json.load(f) 
# Dump the content as a list of words 
info_list = pickle.dumps(info).split('\n') 
# Whenever you see a 'text', collect the second next item 
texts = [info_list[i+2][1:] for i,a in enumerate(info_list) if a.find('text')>0] 
# Output the result 
print texts 

出力は次のようになります。

In [1]: texts 
Out[1]: ['yesterday', 'tomorrow', 'today'] 
+0

これは非常にハッキーで脆弱なアプローチです。これは 'pickle'フォーマットが同じであることに依存しています。これはPython 3で書いたように動作しません。たとえば、私はあなたの結果を再現することはできません、そしておそらくそれはpickleが異なるプロトコルを使用しているからです。私はPython 2.7.12を使っています。 –

関連する問題