python igraph,基于顶点名称/标签的图形相交/并集
我对Python和igraph尤其陌生。在我的学士学位论文中,我必须比较图,从而确定图的交集和并集。我尝试了以下方法:python igraph,基于顶点名称/标签的图形相交/并集,python,graph,igraph,intersection,Python,Graph,Igraph,Intersection,我对Python和igraph尤其陌生。在我的学士学位论文中,我必须比较图,从而确定图的交集和并集。我尝试了以下方法: from igraph import * import json with open('test_graphs.json') as data_file: data = json.load(data_file) test1 = data['test1'] test2 = data['test2'] t1 = Graph(directed=True) for v in
from igraph import *
import json
with open('test_graphs.json') as data_file:
data = json.load(data_file)
test1 = data['test1']
test2 = data['test2']
t1 = Graph(directed=True)
for v in test1:
t1.add_vertex(v)
for v in test1:
for o in test1[v]:
t1.add_edge(v, o)
print(t1)
t2 = Graph(directed=True)
for v in test2:
t2.add_vertex(v)
for v in test2:
for o in test2[v]:
t2.add_edge(v, o)
print(t2)
gr = t1.intersection(t2)
print(gr)
其中,我的json文件如下所示:
{
"test1" : {
"A": ["B","C"],
"B": [],
"C": []
},
"test2" : {
"A": ["B","D"],
"B": [],
"D": []
}
}
我希望交叉口的输出是A->B,但结果是出现了以下输出:
IGRAPH DN-- 3 2 --
+ attr: name (v)
+ edges (vertex names):
A->B, A->C
IGRAPH DN-- 3 2 --
+ attr: name (v)
+ edges (vertex names):
A->B, A->D
IGRAPH D--- 3 2 --
+ edges:
2->0 2->1
第一个和第二个打印的图形显示,两个输入图形都按预期工作(即使很难,我也不明白“attr”来自哪里?)。
但是输出图没有考虑两个图中的顶点A和B是相同的,而C和D是相同的。所以我的问题是:考虑到顶点的标签,如何确定图的交点(并模拟并集) 在由paqmo链接的问题中,维护人员表示,此功能(按顶点名称的并集或交集)在python igraph中不可用。因此,您必须自己编写函数来完成这项工作
这是欧盟的一种做法。将孤立的顶点添加到两个图中,以便它们都具有相同的顶点名称集,然后排列它们的两个顶点集,以便名称的顺序相同。然后标准的union
方法(相当于|
操作符)将做正确的事情。不幸的是,union
方法没有维护属性,因此您必须重新添加名称以及所需的任何其他属性
def named_union(graph1, graph2):
A = graph1.copy()
B = graph2.copy() # so added vertices don't affect original graphs
Anams = set(A.vs['name'])
Bnams = set(B.vs['name'])
A.add_vertices(list(Bnams - Anams))
B.add_vertices(list(Anams - Bnams))
nams = sorted(Anams | Bnams)
Aind = [nams.index(nm) for nm in A.vs['name']]
Bind = [nams.index(nm) for nm in B.vs['name']]
A = A.permute_vertices(Aind) # permute vertices to come in same order as in nams
B = B.permute_vertices(Bind) # ditto
Z = A | B
Z.vs['name'] = nams
return Z
我们可以对交叉点执行类似的操作,除了从每个图中移除不在另一个图中的顶点,然后在使用标准的交叉
方法(或&
操作符)之前,将其余顶点以相同的顺序排列在两个图中
琐事:delete_顶点
在给定一个集合时做正确的事情,但是add_顶点
做不到,除非我们先将集合转换为列表。比如说,一个包含两个元素“A”和“B”的集合会导致添加两个顶点,这两个顶点都命名为{'A','B'}
-这似乎是一个bug。请查看此帖子:
def named_intersect(graph1, graph2):
A = graph1.copy()
B = graph2.copy() # so removed vertices don't affect original graphs
Anams = set(A.vs['name'])
Bnams = set(B.vs['name'])
A.delete_vertices(Anams - Bnams)
B.delete_vertices(Bnams - Anams)
nams = sorted(Anams & Bnams)
Aind = [nams.index(nm) for nm in A.vs['name']]
Bind = [nams.index(nm) for nm in B.vs['name']]
A = A.permute_vertices(Aind)
B = B.permute_vertices(Bind)
Z = A & B
Z.vs['name'] = nams
return Z