python igraph,基于顶点名称/标签的图形交集/联合

时间:2016-12-14 11:12:26

标签: 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 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是。所以我的问题是:考虑到顶点的标签,我如何确定图形的交点(和模拟联合)。

1 个答案:

答案 0 :(得分:2)

在由paqmo链接的问题Perform union of graphs based on vertex names Python igraph中,维护者说这个功能(顶点名称的联合或交叉)在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

我们可以为交点做类似的事情,除了我们从每个图中删除不在另一个图中的顶点,然后在使用标准{{{}之前将其余顶点置换为两个图中的相同顺序1}}方法(或intersection运算符)。

&

琐事: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 在给定集合时做正确的事情,但delete_vertices没有,除非我们先将集合转换为列表。例如,一组有两个元素' A'和' B'导致添加两个顶点,都名为add_vertices - 这似乎是一个错误。