如何在 Networkx 中向网络分析图添加节点和边?

Sam*_*Sam 0 python graph nodes networkx network-analysis

我正在尝试学习网络分析,因此我正在在线使用 Hillary Clinton\xe2\x80\x99s 电子邮件来查看谁给谁发了电子邮件。

\n\n

我的数据位于名为 hrc_dict 的字典中。我有一个发送者和接收者的元组,后面是电子邮件的频率。这是字典的一部分:

\n\n
\n

{(“希拉里·克林顿”,“谢丽尔·米尔斯”):354,(“希拉里·克林顿”,“l”):1,(“琳达·德万”,“希拉里·克林顿”):1,(“希拉里·克林顿”,“卡普里西亚”马歇尔”):9,(“菲利普·克劳利”,“希拉里·克林顿”):2,(“谢丽尔·米尔斯”,“安妮·玛丽·斯劳特”):1}

\n
\n\n

我正在 Jupyter 中使用 Networkx 创建图表。我的代码如下:

\n\n
import networkx as nx\nimport matplotlib.pyplot as plt\n\nG = nx.Graph()\n\nG.add_nodes_from(hrc_dict)\n\nfor s, r in hrc_dict:\n    G.add_edge((s,r), hrc_dict[(s,r)])\n\nG.add_edge((s,r), hrc_dict[(s,r)])\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我调用 nx.Graph() 时,没有任何内容打印出来,当我调用 G.nodes() 时,并非所有节点都显示出来。我在这里粘贴了一些输出:

\n\n
\n

[1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 7,\n 8,\n '马克·佩恩',\n 10,\n ('托德·斯特恩', '希拉里·克林顿'),\n 12,]

\n
\n\n

当我调用 G.edges() 时,我得到以下内容,这似乎是正确的

\n\n
\n

[(1,('希拉里·克林顿','l')),(1,('琳达·德万','希拉里·克林顿')),(1,('希拉里·克林顿','托马斯·香农')),(1 , ('谢丽尔·米尔斯', '安妮·玛丽·斯劳特')), (1, ('克里斯托弗·巴兹吉', '希拉里·克林顿\xe2\x80\x99))]

\n
\n\n

有谁知道如何将节点正确添加到我的图表中。我假设每个人都需要成为一个节点,那么如何分解元组并分别添加名称?边缘显示正确还是我需要以不同的方式输入它们?

\n

Bon*_*fum 5

要将每个人添加为节点,您还需要更改 的使用add_nodes_from

像这样的东西:

srcs, dests = zip(* [(fr, to) for (fr, to) in hrc_dict.keys()])
G.add_nodes_from(srcs+dests)
Run Code Online (Sandbox Code Playgroud)

现在意味着节点列表G.nodes()将是:

['Cheryl Mills',
 'Capricia Marshall',
 'Anne-Marie Slaughter',
 'Phillip Crowley',
 'Hillary Clinton',
 'l',
 'Linda Dewan']
Run Code Online (Sandbox Code Playgroud)

(您不会得到任何重复项,因为 networkx 将图形存储为字典)。

注意:如果您使用下面的方法添加边,则不需要先添加节点 - 但如果由于某种原因您可能拥有没有邻居的节点(或者节点仅是的另一个原因)重要),这段代码可以做到这一点。

然后基本上按照乔尔的回答添加边缘;但还要注意属性“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()
Run Code Online (Sandbox Code Playgroud)

这就是我们可能看到的:

示例输出 - 请注意,由于 HC/A-MS 边缘非常强,因此非常短