我正在尝试学习网络分析,所以我在线使用希拉里克林顿的电子邮件,看谁通过电子邮件发送给谁。
我的数据位于名为hrc_dict的字典中。我有发送者和接收者的元组,然后是电子邮件的频率。这是字典的一部分:
{('Hillary Clinton','Cheryl Mills'):354,('Hillary Clinton','l'):1,('Linda Dewan','Hillary Clinton'):1,''Hillary Clinton' ,'Capricia Marshall'):9,('Phillip Crowley','Hillary Clinton'):2,('Cheryl Mills','Anne-Marie Slaughter'):1}
我在Jupyter中使用Networkx来创建图表。我的代码如下:
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph()
G.add_nodes_from(hrc_dict)
for s, r in hrc_dict:
G.add_edge((s,r), hrc_dict[(s,r)])
G.add_edge((s,r), hrc_dict[(s,r)])
当我调用nx.Graph()时,没有打印出来,当我调用G.nodes()时,并非所有节点都显示出来。我在这里粘贴了一些输出:
[1, 2, 3, 4, 5, 6, 7, 8, '马克佩恩', 10, ('托德斯特恩','希拉里克林顿'), 12,]
当我打电话给G.edges()时,我会得到以下内容,这似乎是正确的
<(1,('Hillary Clinton','l')),(1,('Linda Dewan','Hillary Clinton')),(1,('Hillary Clinton','Thomas Shannon')) ,(1,('Cheryl Mills','Anne-Marie Slaughter')),(1,('Christopher Butzgy','希拉里克林顿'))]
有谁知道如何正确地将节点添加到我的图表中。我假设每个人都需要成为一个节点,那么如何分解元组并单独添加名称呢?边缘是否正确显示还是需要以不同方式输入?
答案 0 :(得分:3)
要将每个人添加为节点,您还需要更改add_nodes_from
。
这样的事情:
srcs, dests = zip(* [(fr, to) for (fr, to) in hrc_dict.keys()])
G.add_nodes_from(srcs+dests)
现在意味着来自G.nodes()
的节点列表将是:
['Cheryl Mills',
'Capricia Marshall',
'Anne-Marie Slaughter',
'Phillip Crowley',
'Hillary Clinton',
'l',
'Linda Dewan']
(因为networkx将图形存储为字典,所以不会有任何重复。)
注意:如果您使用下面的方法添加边缘,则不需要首先添加节点 - 但是如果有某些原因可能导致您没有邻居的节点(或其他原因)只有节点很重要),这段代码就可以了。
然后根据Joel的答案基本添加边缘;还要注意使用属性“weight”,因此布局可以直接利用信息。
import networkx as nx
import matplotlib.pyplot as plt
hrc_dict = {('Hillary Clinton', 'Cheryl Mills'): 355, ('Hillary Clinton', 'l'): 1, ('Linda Dewan', 'Hillary Clinton'): 1, ('Hillary Clinton', 'Capricia Marshall'): 9, ('Phillip Crowley', 'Hillary Clinton'): 2, ('Cheryl Mills', 'Anne-Marie Slaughter'): 1}
G = nx.Graph()
# To add the a node for each of the email parties:
srcs, dests = zip(* [(fr, to) for (fr, to) in hrc_dict.keys()])
G.add_nodes_from(srcs + dests)
# (but it isn't needed IF the following method is used
# to add the edges, since add_edge also creates the nodes if
# they don't yet exist)
# note the use of the attribute "weight" here
for (s,r), count in hrc_dict.items():
G.add_edge(s, r, weight=count)
# produce info to draw:
# a) if weight was used above, spring_layout takes
# into account the edge strengths
pos = nx.spring_layout(G)
# b) specifiy edge labels explicitly
# method from https://groups.google.com/forum/#!topic/networkx-discuss/hw3OVBF8orc
edge_labels=dict([((u,v,),d['weight'])
for u,v,d in G.edges(data=True)])
# draw it
plt.figure(1);
nx.draw_networkx(G, pos, with_labels=True)
nx.draw_networkx_edge_labels(G,pos,edge_labels=edge_labels)
plt.axis('equal') # spring weighting makes more sense this way
plt.show()
这就是我们可能会看到的:
答案 1 :(得分:0)
你的问题基本上就在这一点:
G.add_edge((s,r), hrc_dict[(s,r)])
networkx将此解释为“在第一个参数(s,r)
和第二个参数hrc_dict[(s,r)]
之间添加边缘。”因此,例如('Hillary Clinton', 'Cheryl Mills'): 354
成为节点('Hillary Clinton', 'Cheryl Mills')
和节点354
之间的边缘。而是尝试
G.add_edge(s, r, count = hrc_dict[(s,r)])