第一部分:节点
每个节点在一行中显示如下:号码,电话号码,姓名,城市,花费的总时间;其中number是从1开始的标识节点的序号。花费的总时间是电话号码发起的呼叫的总秒数。
第二部分:边缘
每条边在一行中显示如下:原点数,目的地数,重量;其中数字原点和目的地是标识文件第一部分中节点的数字。
callgraph.txt文件的示例可能如下所示。请注意,节点按电话号码排序。
2, 7801234567, Ameneh Gholipour Shahraki, Hinton, 198473
7, 7801236789, Stuart Johnson, Saint Albert, 64399
4, 7803214567, Md Toukir Imam, Sherwood Park, 179532
8, 7804321098, Hamman Samuel, Stony Plain, 57909
1, 7804922860, Osmar Zaiane, Edmonton, 250068
5, 7807890123, Elham Ahmadi, Devon, 129370
9, 7808765432, Amir Hossein Faghih Dinevari, Beaumont, 62552
6, 7808907654, Weifeng Chen, Spruce Grove, 121726
3, 7809876543, Farrukh Ahmed, Edson, 190211
2, 7, 40425
2, 4, 21618
2, 8, 34186
2, 1, 34291
2, 5, 24286
2, 9, 67786
2, 6, 21983
2, 3, 35614
7, 4, 32851
7, 8, 27293
7, 1, 45367
现在我看到的第一部分很容易完成:
customers=open('customers.txt','r')
calls=open('calls.txt.','r')
nodes= {}
name={}
city={}
total_spent_time={}
with open("customers.txt") as fp:
for line in fp:
number = line.split(";")[0]
if number not in nodes:
nodes[number] = len(nodes) + 1
rows=line.split(";")
name[rows[0]]=rows[1]
city[rows[0]]=rows[2].strip("\n")
with open("calls.txt") as fp2:
for lines in fp2:
rows2=lines.split(";")
if rows2[1] not in total_spent_time:
total_spent_time[rows2[1]]=int(rows2[3])
elif rows2[1] in total_spent_time:
total_spent_time[rows2[1]]+=int(rows2[3])
print(total_spent_time)
但这是我最困难的第二部分;例如,我必须为每个唯一的电话#分配一个节点号,然后如示例文件所示,计算每个节点与另一个节点通话的时间等等。
我从中获得唯一编号的文件在这里: http://pastebin.com/xMx15nCS
这些数字之间包含数千个电话的文件在这里: http://pastebin.com/RSMnXDtq
第二行calls.txt是发起者#,第三行是接收者#,第四行是这两个数字之间总共谈话的秒数。
我如何分配节点,计算每个数字之间的总时间,同时将它们用作节点?
编辑:我想在调用者和接收者之间制作一个元组,它有效!但现在我需要为它们分配节点号,我该怎么做呢?这是我添加的内容:
nodes_g={}
with open("calls.txt") as fp3:
for line in fp3:
rows3=line.split(";")
x,node1,node2,sec,y=line.split(";")
if node1 not in nodes_g:
nodes_g[node1]=node2
print(nodes_g)
EDIT2:尝试将“节点”字典与另一个字典组合以计算每个数字之间的总次数;因为我收到一个错误,说字典在python中不可用,所以进展不顺利。任何人都可以告诉我一个解决方法吗?
nodes_g={}
complete={}
with open("calls.txt") as fp3:
for line in fp3:
rows3=line.split(";")
x,node1,node2,sec,y=line.split(";")
if node1 not in nodes_g:
nodes_g[node1]=node2
else:
nodes_g[node1]=node2
for k,v in nodes_g.items():
if node1 in nodes_g and node1!=node2:
nodes_g[node1]=node2
for k,v in nodes_g.items():
if node1 and node2 in nodes_g:
complete[nodes_g]=sec
else:
complete[nodes_g]+=sec
print(complete)
EDIT3: 我尝试使用嵌套在dict中的元组,但由于某种原因它不会添加值,而只是将它替换为下一行的值而不添加它们??
nodes_g={}
complete={}
with open("calls.txt") as fp3:
for line in fp3:
rows3=line.split(";")
x,node1,node2,sec,y=line.split(";")
if node1 not in nodes_g:
nodes_g[node1,node2]=int(sec)
if node1 in nodes_g and node2 in nodes_g:
nodes_g[node1,node2]+=int(sec)
print(nodes_g)
print(nodes_g)
答案 0 :(得分:0)
如果您只想要样本文件第二部分第一行的每个不同(目标,收件人)对(2,7 ...)的总时间...那么我就创建了带有元组((2,7),(2,4),(2,8)等的字典作为键和这些对话的总和(最初设置为(40425,21618,34186)作为值。< / p>
换句话说,如果第一个调用是从第2点到第7点并持续40425秒(?),那么只需创建一个包含键(2,7)
和初始值40425
的字典条目。 ..如果您遇到2到7之间的另一个电话,那么将它的值添加到您的总和中(例如my_report[(2,7)]+=XXXX
)。
这会产生从7到2的呼叫的单独条目。但是,您使用tuple(sorted((x,y))
作为在一个键下在两个方向上对呼叫求和的键。换句话说,无论哪一端发起呼叫,都会产生所有不同配对的报告。
顺便提一下,您可以使用if *somekey* not in *mydict*: ...
来减少mydict[somekey] = mydict.get(somekey, 0) + value
混乱...这将保持总和,并为之前不存在的任何密钥提供默认值零。这是一个常见的Pythonic微优化,它可以替代代码末尾的四行代码来自&#34; EDIT3&#34;用一条相对容易阅读的单行。
我承认我没有信心正确地解释你的意图。我注意到您的代码示例分为; ,您的示例数据片段似乎是,分隔。我认为这只是一些编辑/粘贴错误。
#!/usr/bin/python
from __future__ import print_function # make example work for Python 2.7+ or 3.x
# ...
# ...
my_report = dict()
for line in fp3:
try:
row = tuple([int(x) for x in line.split(",", 3)])
except ValueError, e:
print("Corrupt data?: %s" % line, file=sys.stderr)
continue
key = row[:2]
my_report[key] = my_report.get(key, 0) + row[3]
# print(my_report)
for node_pair, total in sorted(my_reports.iteritems()):
print("%s: %d" % (node_pair, total))
(尽管您可能更喜欢输出的某些格式和排序;如图所示)。