0

次の形式のデータがあります。

id1 id2 値のようなもの

1   234  0.2
1   235  0.1

等々。json形式に変換したい:

{
  "nodes": [ {"name":"1"},  #first element
             {"name":"234"}, #second element
             {"name":"235"} #third element
             ] ,
   "links":[{"source":1,"target":2,"value":0.2},
             {"source":1,"target":3,"value":0.1}
           ]
}

したがって、元のデータから上記の形式へ.. ノードには、元のデータに存在する (個別の) 名前のすべてのセットが含まれ、リンクは基本的に、ノードによって返される値リスト内のソースとターゲットの行番号です。例えば:

   1 234 0.2

1 は、キー「nodes」が保持する値のリストの最初の要素にあります 234 は、キー「nodes」が保持する値のリストの 2 番目の要素です

したがって、リンク ディクショナリは {"source":1,"target":2,"value":0.2} です。

Pythonでこれを効率的に行うにはどうすればよいですか..私がやっていることよりも良い方法があるはずです。

def open_file(filename,output=None):
    f = open(filename,"r")
    offset = 3429
    data_dict = {}
    node_list = []
    node_dict = {}
    link_list = []
    num_lines = 0
    line_ids = []
    for line in f:
        line = line.strip()
        tokens = line.split()
        mod_wid  = int(tokens[1]) + offset


        if not node_dict.has_key(tokens[0]):
            d = {"name": tokens[0],"group":1}
            node_list.append(d)
            node_dict[tokens[0]] = True
            line_ids.append(tokens[0])
        if not node_dict.has_key(mod_wid):
            d = {"name": str(mod_wid),"group":1}
            node_list.append(d)
            node_dict[mod_wid] = True
            line_ids.append(mod_wid)


        link_d = {"source": line_ids.index(tokens[0]),"target":line_ids.index(mod_wid),"value":tokens[2]}
        link_list.append(link_d)
        if num_lines > 10000:
            break
        num_lines +=1


    data_dict = {"nodes":node_list, "links":link_list}

    print "{\n"
    for k,v in data_dict.items():
        print  '"'+k +'"' +":\n [ \n " 
        for each_v in v:
            print each_v ,","
        print "\n],"
    print "}"

open_file("lda_input.tsv")
4

2 に答える 2

2

「効率的に」とは、ランタイム速度の効率ではなく、プログラマーの効率 (ロジックの読み取り、保守、およびコーディングがいかに簡単か) について話していることを前提としています。後者について心配している場合は、理由もなく心配している可能性があります。(ただし、以下のコードはおそらくとにかく高速です。)

より良い解決策を考え出すための鍵は、より抽象的に考えることです。テキスト ファイルの行ではなく、CSV ファイルの行について考えてください。dict文字列処理によって JSON を生成しようとするのではなく、JSON でレンダリングできる を作成します。繰り返し実行したい場合は、関数にまとめます。など。次のようなもの:

import csv
import json
import sys

def parse(inpath, namedict):
    lastname = [0]
    def lookup_name(name):
        try:
            print('Looking up {} in {}'.format(name, names))
            return namedict[name]
        except KeyError:
            lastname[0] += 1
            print('Adding {} as {}'.format(name, lastname[0]))
            namedict[name] = lastname[0]
            return lastname[0]
    with open(inpath) as f:
        reader = csv.reader(f, delimiter=' ', skipinitialspace=True)
        for id1, id2, value in reader:
            yield {'source': lookup_name(id1),
                   'target': lookup_name(id2),
                   'value': value}

for inpath in sys.argv[1:]:
    names = {}
    links = list(parse(inpath, names))
    nodes = [{'name': name} for name in names]
    outpath = inpath + '.json'
    with open(outpath, 'w') as f:
        json.dump({'nodes': nodes, 'links': links}, f, indent=4)
于 2013-02-06T01:49:17.830 に答える
1

JSON を手動で作成しないでください。jsonモジュールを使用して既存の Python オブジェクトから作成します。

def parse(data):
    nodes = set()
    links = set()

    for line in data.split('\n'):
        fields = line.split()

        id1, id2 = map(int, fields[:2])
        value = float(fields[2])

        nodes.update((id1, id2))
        links.add((id1, id2, value))

    return {
        'nodes': [{
            'name': node
        } for node in nodes],
        'links': [{
            'source': link[0],
            'target': link[1],
            'value': link[2]
        } for link in links]
    }

json.dumpsこれで、文字列を取得するために使用できます。

>>> import json
>>> data = '1   234  0.2\n1   235  0.1'
>>> parsed = parse(data)
>>> parsed
    {'links': [{'source': 1, 'target': 235, 'value': 0.1},
  {'source': 1, 'target': 234, 'value': 0.2}],
 'nodes': [{'name': 1}, {'name': 234}, {'name': 235}]}
>>> json.dumps(parsed)
    '{"nodes": [{"name": 1}, {"name": 234}, {"name": 235}], "links": [{"source": 1, "target": 235, "value": 0.1}, {"source": 1, "target": 234, "value": 0.2}]}'
于 2013-02-06T01:25:10.647 に答える