如何将元组的网络边缘属性列表提取到元组字典对字典(边缘标签)?

2024-09-30 14:15:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带有边和边属性的网络图。我正在尝试使用

sub_gr.edges(data=True)

edge_labels = list(sub_gr.edges(data=True))
[(1405394338,
  1367797753,
  {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
   'Phone': 5392353776,
   'VIN': '1C3CDZBG9DN5907'}),
 (1405394338, 1354581834, {'Phone': 5392353776}),
 (1405394338,
  1334448011,
  {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM', 'Phone': 5392353776}),
 (1405394338, 1244950426, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'}),
 (1354581834, 1367797753, {'Phone': 5392353776}),
 (1354581834, 1334448011, {'Phone': 5392353776}),
 (1334448011,
  1367797753,
  {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM', 'Phone': 5392353776}),
 (1334448011, 1244950426, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'}),
 (1367797753, 1244950426, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'})]

返回包含节点和边属性的元组列表

现在我想把它转换成

{(1334448011, 1244950426): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'},
 (1334448011, 1367797753): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
  'Phone': 5392353776},
 (1354581834, 1334448011): {'Phone': 5392353776},
 (1354581834, 1367797753): {'Phone': 5392353776},
 (1367797753, 1244950426): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'},
 (1405394338, 1244950426): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'},
 (1405394338, 1334448011): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
  'Phone': 5392353776},
 (1405394338, 1354581834): {'Phone': 5392353776},
 (1405394338, 1367797753): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
  'Phone': 5392353776,
  'VIN': '1C3CDZBG9DN5907'}}

元组字典,作为值的键和属性

在边缘标签中使用的步骤

nx.draw_networkx_edge_labels(sub_gr,pos,edge_labels=edge_labels,font_color='red')

有办法做到这一点吗


Tags: comtruedatalabels属性emailphonegmail
2条回答

假设模式总是相同的:edge_lables中的前两个元素应该是键,第三个元素是值,然后可以使用字典理解

d = {x[:2]: x[2:][0] for x in edge_labels}

{(1405394338, 1367797753): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
  'Phone': 5392353776,
  'VIN': '1C3CDZBG9DN5907'},
 (1405394338, 1354581834): {'Phone': 5392353776},
 (1405394338, 1334448011): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
  'Phone': 5392353776},
 (1405394338, 1244950426): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'},
 (1354581834, 1367797753): {'Phone': 5392353776},
 (1354581834, 1334448011): {'Phone': 5392353776},
 (1334448011, 1367797753): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
  'Phone': 5392353776},
 (1334448011, 1244950426): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'},
 (1367797753, 1244950426): {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'}}

networkx中,我可以想出两种很好的方法来解决这个问题。第一种方法是为每个字段制作单独的标签,并以不同的颜色打印,如下所示:

import networkx as nx
import matplotlib.pyplot as plt

# Create the graph from the example edgelist
edges=[(1405394338,
  1367797753,
  {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM',
   'Phone': 5392353776,
   'VIN': '1C3CDZBG9DN5907'}),
 (1405394338, 1354581834, {'Phone': 5392353776}),
 (1405394338,
  1334448011,
  {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM', 'Phone': 5392353776}),
 (1405394338, 1244950426, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'}),
 (1354581834, 1367797753, {'Phone': 5392353776}),
 (1354581834, 1334448011, {'Phone': 5392353776}),
 (1334448011,
  1367797753,
  {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM', 'Phone': 5392353776}),
 (1334448011, 1244950426, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'}),
 (1367797753, 1244950426, {'Email': 'NJOHNSONJOHNSON34@GMAIL.COM'})]
G=nx.DiGraph(edges)

# Grab the labels individually
labels1=nx.get_edge_attributes(G,'Email')
labels2=nx.get_edge_attributes(G,'Phone')
labels3=nx.get_edge_attributes(G,'VIN')

# Setup the figure and plot it
plt.figure(figsize=(15,15))
pos=nx.spring_layout(G)
nx.draw(G,pos)

# Add each label individually
nx.drawing.draw_networkx_edge_labels(G,pos,edge_labels=labels1,font_color='red',label_pos=0.75,rotate=True)
nx.drawing.draw_networkx_edge_labels(G,pos,edge_labels=labels2,font_color='blue',label_pos=0.5,rotate=True)
nx.drawing.draw_networkx_edge_labels(G,pos,edge_labels=labels3,font_color='green',label_pos=0.25,rotate=True)

# display
plt.show()

本例中的图形如下所示: enter image description here

另一个是制作自定义标签,如下所示:

# Setup the figure and plot it
plt.figure(figsize=(15,15))
pos=nx.spring_layout(G)
nx.draw(G,pos)

custom_labels = {}
for u,v,d in G.edges(data=True):
    L=""
    for att,val in d.items():
        L+=att+":"+str(val)+"\n"
    custom_labels[(u,v)]=L

nx.drawing.draw_networkx_edge_labels(G,pos,edge_labels=custom_labels,font_color='red',
                                     rotate=False,horizontalalignment ='left')

在本例中,该图如下所示: enter image description here

当然,您可以使用figsize和font参数使这些更漂亮。此外,我个人建议使用yED(https://www.yworks.com/products/yed)或其他图形界面来实现这类功能。您可以使用nx.write_graphml(G, "filename.graphml")导出到可以读入的文件,然后使用它的属性映射器和布局工具进行设置。如果要查看大量绘图,这会很乏味,但如果要制作“最终版本”图形,它确实是一个更好的工具,因为可以轻松微调各个节点、边和标签的位置。(这就是我如何为我的研究论文和会议幻灯片制作99%的网络数据。)

编辑为完整起见,我将在此处输入导出代码和我为其制作的图形:

# Make a copy for export
G_ex=G.copy()

# Add the custom labels we made earlier 
# to the copy graph as an attribute
for u,v in custom_labels:
    G_ex.edges[(u,v)]['label']=custom_labels[(u,v)]

# Convert the attributes to strings to avoid import headaches
for e in G_ex.edges():
    for k,v in G_ex.edges[e].items():
        G_ex.edges[e][k]=str(v)

# Actually do the exporting
nx.write_graphml(G_ex,"test.graphml")

我将graphml文件导入到yED中,并对其进行处理,直到得到以下结果: enter image description here

相关问题 更多 >

    热门问题