web-dev-qa-db-ja.com

networkxグラフを結合(結合)する

2つのnetworkxグラフ、GHがあるとします。

_G=nx.Graph()
fromnodes=[0,1,1,1,1,1,2]
tonodes=[1,2,3,4,5,6,7]
for x,y in Zip(fromnodes,tonodes):
    G.add_Edge(x,y)

H=nx.Graph()
fromnodes=range(2,8)
tonodes=range(8,14)
for x,y in Zip(fromnodes,tonodes):
    H.add_Edge(x,y)
_

2つのnetworkxグラフを結合する最良の方法は何ですか?

ノード名を保持したいと思います(2〜7の共通ノードに注意してください)。 nx.disjoint_union(G,H)を使用したとき、これは起こりませんでした:

_>>> G.nodes()
[0, 1, 2, 3, 4, 5, 6, 7]
>>> H.nodes()
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
>>> Un= nx.disjoint_union(G,H)
>>> Un.nodes()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
# 
_

Hノードラベルが変更されました(必要なものではありません)。同じ番号のノードでグラフを結合したい。

注。これは NetworkXで2つの重み付きグラフを結合するの複製ではありません

21
atomh33ls

探している関数は compose で、両方のグラフにあるすべてのエッジとすべてのノードを含むグラフを生成します。両方のグラフに同じ名前のノードがある場合、単一のコピーが新しいグラフになります。同様に、両方に同じエッジが存在する場合。次に、エッジ/ノード属性を含む例を示します。

import networkx as nx

G=nx.Graph()
G.add_node(1, weight = 2)
G.add_node(2, weight = 3)
G.add_Edge(1,2, flux = 5)
G.add_Edge(2,4)

H=nx.Graph()
H.add_node(1, weight = 4)
H.add_Edge(1,2, flux = 10)
H.add_Edge(1,3) 

F = nx.compose(G,H)
#F has all nodes & edges of both graphs, including attributes
#Where the attributes conflict, it uses the attributes of H.

G.nodes(data=True)
> NodeDataView({1: {'weight': 2}, 2: {'weight': 3}, 4: {}})
H.nodes(data=True)
> NodeDataView({1: {'weight': 4}, 2: {}, 3: {}})
F.nodes(data=True)
> NodeDataView({1: {'weight': 4}, 2: {'weight': 3}, 4: {}, 3: {}})

G.edges(data=True)
> EdgeDataView([(1, 2, {'flux': 5}), (2, 4, {})])
H.edges(data=True)
> EdgeDataView([(1, 2, {'flux': 10}), (1, 3, {})])
F.edges(data=True)
EdgeDataView([(1, 2, {'flux': 10}), (1, 3, {}), (2, 4, {})])

これらは属性を保持しますが、明らかに競合がある場合、これは不可能です。 Hの属性が優先されます。

対称差、交差 、...を実行する他のオプションもあります.

結合するグラフが複数ある場合は、 compose_all 。これは、composeの周りにforループをラップするだけです。

41
Joel

これでした。

   U=nx.Graph()
   U.add_edges_from(G.edges()+H.edges())
   U.add_nodes_from(G.nodes()+H.nodes()) #deals with isolated nodes

または、Edge属性を保持します。

   U.add_edges_from(G.edges(data=True)+H.edges(data=True))

また、ノードの属性も保持するには:

   U.add_nodes_from(G.nodes(data=True)+H.nodes(data=True))
9
atomh33ls