私が持っているもの:networkxにインポートされた、ノードとエッジがgmlファイルによって読み込まれたグラフG.
問題:選択したエッジEに新しい属性を追加する方法。
やりたいこと:グラフの特定のエッジEに新しい属性「タイプ」を追加したい。注意:属性 'type'はこのEdge Eには存在しません。
私のコードは:
G.Edge[id_source][id_target]['type']= value
しかし、Gのすべてのエッジを印刷すると、n + 1のエッジになります。 Gのすべての古いエッジと新しいエッジp =(id_source、id_target、{'type' = value})。さらに、古いEdge E(私が変更したいもの)には、新しい属性 'type'がありません。
したがって、私のコードは新しいEdgeを追加しました(私は必要ありません)。
更新したい存在しない新しい属性を追加する古いもの。
グラフの代わりにnetworkx MultiGraphを使用している場合、エッジの属性設定は少しトリッキーです。 (ノード間に複数のエッジを持つグラフをロードすることにより、マルチグラフを取得できます)。 G.Edge[id_source][id_target]['type']= value
が必要なときに属性G.Edge[id_source][id_target][key]['type']= value
を割り当てて、データ構造を破壊している可能性があります。
以下は、グラフとマルチグラフで動作が異なる例です。
グラフの場合、属性は次のように機能します。
In [1]: import networkx as nx
In [2]: G = nx.Graph()
In [3]: G.add_Edge(1,2,color='red')
In [4]: G.edges(data=True)
Out[4]: [(1, 2, {'color': 'red'})]
In [5]: G.add_Edge(1,2,color='blue')
In [6]: G.edges(data=True)
Out[6]: [(1, 2, {'color': 'blue'})]
In [7]: G[1][2]
Out[7]: {'color': 'blue'}
In [8]: G[1][2]['color']='green'
In [9]: G.edges(data=True)
Out[9]: [(1, 2, {'color': 'green'})]
マルチグラフでは、平行エッジを追跡するためのキーの追加レベルがあるため、動作が少し異なります。キーを明示的に設定しない場合、MultiGraph.add_Edge()は、内部的に選択されたキー(連続した整数)で新しいEdgeを追加します。
In [1]: import networkx as nx
In [2]: G = nx.MultiGraph()
In [3]: G.add_Edge(1,2,color='red')
In [4]: G.edges(data=True)
Out[4]: [(1, 2, {'color': 'red'})]
In [5]: G.add_Edge(1,2,color='blue')
In [6]: G.edges(data=True)
Out[6]: [(1, 2, {'color': 'red'}), (1, 2, {'color': 'blue'})]
In [7]: G.edges(data=True,keys=True)
Out[7]: [(1, 2, 0, {'color': 'red'}), (1, 2, 1, {'color': 'blue'})]
In [8]: G.add_Edge(1,2,key=0,color='blue')
In [9]: G.edges(data=True,keys=True)
Out[9]: [(1, 2, 0, {'color': 'blue'}), (1, 2, 1, {'color': 'blue'})]
In [10]: G[1][2]
Out[10]: {0: {'color': 'blue'}, 1: {'color': 'blue'}}
In [11]: G[1][2][0]['color']='green'
In [12]: G.edges(data=True,keys=True)
Out[12]: [(1, 2, 0, {'color': 'green'}), (1, 2, 1, {'color': 'blue'})]
属性を1つのエッジのみに追加する理由がよくわかりません。代わりに、すべてのエッジに属性を追加してから、特定のエッジにthe wanted value
を与えることができます。
Networkxにはset_Edge_attributes
というメソッドがあります。たとえば、すべてのエッジにエッジ属性を追加できます。
G = nx.path_graph(3)
bb = nx.Edge_betweenness_centrality(G, normalized=False)
nx.set_Edge_attributes(G, 'betweenness', bb)
G[1][2]['betweenness']
出力:2.0
OPの質問から追加されたソリューション:
アリックといくつかのトリックのおかげで問題を解決しました:
def add_attribute_to_Edge(H,id_node_source,id_node_target,new_attr,value_attr): keydict =H[id_node_source][id_node_target] key=len(keydict) for k in keydict: if 'type' not in H.Edge[id_source][id_target][k]: H.add_Edge(id_node_source,id_node_target,key=k, new_attr= value_attr)
実際、新しい属性をグラフの既存のEdgeに追加するためのより良い、短い方法があります。
>>> for itr in G.edges_iter(None, True, True):
itr
(0, 1, {})
(0, 2, {'Edge': (0, 2)})
(0, 3, {})
(0, 4, {})
(1, 2, {})
(1, 3, {})
(2, 3, {})
(2, 4, {})
(3, 4, {})
>>> G[0][1].update(Edge=(0,1)) #This will add 'Edge'=(0,1) dict item to Edge(0,1)
>>> for itr in G.edges_iter(None, True, True):
itr
(0, 1, {'Edge': (0, 1)})
(0, 2, {'Edge': (0, 2)})
(0, 3, {})
(0, 4, {})
(1, 2, {})
(1, 3, {})
(2, 3, {})
(2, 4, {})
(3, 4, {})
Xin-Feng Liによる以下の回答は機能します。values
とname
の引数がNetworkx v1.x(回答が最初に書かれたとき)とNetworkx v2.xの間で切り替わったことに注意してください。 v2.xの場合、コードは次のとおりです。
G = nx.path_graph(3)
bb = nx.Edge_betweenness_centrality(G, normalized=False)
nx.set_Edge_attributes(G, bb, 'betweenness')
G[1][2]['betweenness']