Python NetworkX - получить DiGraph из вложенных словарей
Я пытаюсь создать простой DiGraph в Python NetworkX из вложенного словаря, но похоже, что встроенная инициализация не создает конечные конечные узлы.
Пример игрушки:
class_hierarchy= {-1: ["A", "B"],
"A":{"A1":[1], "A2":[3,4]},
"B": {"B1":[5,6], "B2": [7,8]}}
Построение графика:
G = DiGraph(class_hierarchy)
Теперь посмотрим, что в нем есть:
G.nodes
Out[86]: NodeView((-1, 'A', 'B', 'A1', 'A2', 'B1', 'B2'))
Похоже, что конечные узлы не добавляются
Проверяем это:
list(G.successors('A'))
Out[88]: ['A1', 'A2']
Выглядит разумно
Но:
list(G.successors('A1'))
Out[89]: []
Я не уверен, почему это так? Документация для NetworkX указывает, что:
входящие_график_данные (входной граф (необязательно, по умолчанию: нет)) - данные для инициализации графа. Если Нет (по умолчанию), создается пустой график. Данные могут быть любого формата, который поддерживается функцией to_networkx_graph(), в настоящее время включает в себя список фронтов, диктов диктов, диктов списков и т. Д.
Есть идеи, что я делаю не так?
1 ответ
У вас есть смешанный вход, который является одновременно dict of lists
и оба dict of dicts
,Networkx
будет интерпретировать это как dict of lists
,
Смотрите следующий код, где data
является class_hierarchy
в твоем случае.
if isinstance(data, dict):
try:
#this will raise an exception
return from_dict_of_dicts(data, create_using=create_using,
multigraph_input=multigraph_input)
except:
try:
# this is what is called in your case
return from_dict_of_lists(data, create_using=create_using)
except:
raise TypeError("Input is not known type.")
В твоем случае, networkx
ожидает словарь списков представления смежности.
Например, ожидаемый ввод имеет вид: key: value
-> node u: list of nodes [v1,v2,...,vn] u is connected with
(например, {0: [1,2], 1: [3,4]}.
То, что networkx делает с вашим вводом, вы даете следующим образом:
G=nx.DiGraph()
edges_list = [((node, nbr)) for node, nbrlist in d.items() for nbr in nbrlist]
# [(-1, 'A'), (-1, 'B'), ('A', 'A1'), ('A', 'A2'), ('B', 'B1'), ('B', 'B2')]
G.add_edges_from(edges_list)
Таким образом, вы должны изменить свой формат в соответствии со значением, которое вы ему даете.