在Python中以所需格式格式化字符串
我有以下格式的数据: id1 id2值 差不多在Python中以所需格式格式化字符串,python,d3.js,Python,D3.js,我有以下格式的数据: 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,"targe
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”保留的值列表中的第二个元素
因此,链接字典是{“源”:1,“目标”:2,“值”:0.2}
如何在python中高效地执行此操作。。我相信应该有比我现在做的更糟糕的事情:(
这就是我正在做的
从集合导入defaultdict
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")
不要手动构造JSON。使用
JSON
模块从现有的Python对象中构造JSON:
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}]}'
不要手动构造JSON。使用
JSON
模块从现有的Python对象中构造JSON:
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}]}'
我假设“高效”指的是程序员的效率,即逻辑的读取、维护和编码有多容易,而不是运行时的速度效率。如果您担心后者,您可能会无缘无故地担心(但下面的代码可能会更快)
想出更好的解决方案的关键是更抽象地思考。考虑CSV文件中的行,而不是文本文件中的行;创建一个可以用JSON呈现的dict
,而不是试图通过字符串处理生成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)
我假设“高效”指的是程序员的效率,即逻辑的读取、维护和编码有多容易,而不是运行时的速度效率。如果您担心后者,您可能会无缘无故地担心(但下面的代码可能会更快)
想出更好的解决方案的关键是更抽象地思考。考虑CSV文件中的行,而不是文本文件中的行;创建一个可以用JSON呈现的dict
,而不是试图通过字符串处理生成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)
你想要和。所谓“高效”是指“使用更少的CPU时间”还是“使用更少的程序员时间”?你想要和。所谓“高效”是指“使用更少的CPU时间”还是“使用更少的程序员时间”?不,这与他要求的输出不同。注意,他的
链接类似于{源代码:1,'target':2,'value':0.1}
-换句话说,每一个都是节点
列表中名称的(基于1的)索引,而不是实际名称。因此,您不能在此处使用集合;您必须使用dict
(或列表
,但这可能会更复杂)不,这与他要求的输出不同。请注意,他的链接类似于{'source':1,'target':2,'value':0.1}
——换句话说,每个链接都是节点列表中名称的(基于1的)索引,而不是实际名称。因此,这里不能使用集合;必须使用dict
(或者是列表
,但这可能会更复杂)。