goduni

日記&備忘録

NetworkXを使用時に生じた"TypeError: function takes 3 positional arguments but 4 were given"の解決策

研究の一環でネットワーク図を出力する必要ができたので,以下のサイトを参考にPythonのNetworkXを使用した.

qiita.com


その際,以下のコードを実行時にエラーが生じた

--- 該当コード ---
for tags in tags_list:
    for node0,node1 in itertools.combinations(tags, 2):
        if not G.has_node(node0) or not G.has_node(node1):
            continue
        if G.has_edge(node0, node1):
            G.edge[node0][node1]["weight"] += 1
        else:
            G.add_edge(node0, node1, {"weight":1})


--- エラー内容 ---
--------------------------------------
TypeErrorTraceback (most recent call last)
<ipython-input-257-8dcf61b27f82> in <module>
      6             G.edge[node0][node1]["weight"] += 1
      7         else:
----> 8             G.add_edge(node0, node1, {"weight":1})

TypeError: add_edge() takes 3 positional arguments but 4 were given

add_edge関数の引数関係でエラーが生じている.


とりあえずググってみる

StackOverflowで似たような質問があった.
stackoverflow.com

解決策として挙げられていた以下のコードを実行したが,以前エラー内容は変わらず...

--- 解決策1 ---
cities.add_edge('Boston', 'Nashville', distance=0.4})

--- 解決策2 ---
cities.add_edge('Boston', 'Nashville', attr_dict = {'distance':0.4})

調べたところ,バージョンの問題でもなさそうなのでよく分からない.



公式ドキュメントを見てみる

networkx.github.io


公式ドキュメントのチュートリアルを読み進めていくと以下の記述を発見!

Edge Attributes

Add/change edge attributes using add_edge(), add_edges_from(), or subscript notation.

G.add_edge(1, 2, weight=4.7 )
G.add_edges_from([(3, 4), (4, 5)], color='red')
G.add_edges_from([(1, 2, {'color': 'blue'}), (2, 3, {'weight': 8})])
G[1][2]['weight'] = 4.7
G.edges[3, 4]['weight'] = 4.2

どうにも,add_edgeを用いる場合は辞書型{}のように記述するのではなく,weight=4.7のようにそのまま記述するっぽい?



該当箇所を修正して実行

--- 修正前 ---
for tags in tags_list:
    for node0,node1 in itertools.combinations(tags, 2):
        if not G.has_node(node0) or not G.has_node(node1):
            continue
        if G.has_edge(node0, node1):
            G.edge[node0][node1]["weight"] += 1
        else:
            G.add_edge(node0, node1, {"weight":1})

--- 修正後 ---
for tags in tags_list:
    for node0,node1 in itertools.combinations(tags, 2):
        if not G.has_node(node0) or not G.has_node(node1):
            continue
        if G.has_edge(node0, node1):
            G[node0][node1]["weight"] += 1 # <--- 修正箇所
        else:
            G.add_edge(node0, node1, weight=1) # <--- 修正箇所

実行したところ,エラーが出ることなく無事に処理が完了した!!


実際に,中身も確認したところ...

G['Python']['Django']
>>> {'weight': 8}

問題なくweightの値が更新されていた!





英語で書かれているので避けてるけど,公式ドキュメントを読むことって大事やな,って思った.
あと今回参考にしたQiitaの記事の最終更新日時は2016年08月31日だったので,もしかしたら当時と今では異なるだけなのかも