При запуске приведенного ниже кода NetworkX python 3.5 (в Jupyter) я получаю сообщение об ошибке, которое я не совсем понимаю. Любая помощь приветствуется.
import pandas as pd
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import os, warnings
warnings.filterwarnings('ignore')
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
## NODES
a = [ ( 'a_%d' % i, {'a' : i}) for i in range(0,5) ]
b = [ ( 'b_%d' % i, {'b' : i}) for i in range(0,5) ]
c = [ ( 'c_%d' % i, {'c' : i}) for i in range(0,5) ]
d = [ ( 'd_%d' % i, {'d' : i}) for i in range(0,5) ]
E = [ ( 'E_%d' % h, {'a': i}, {'b': j}, {'c': k}, {'d': l} )
for h in range(1,626) for i in range(0,5)
for j in range(0,5) for k in range(0,5)
for l in range(0,5) ]
## GRAPH initialization
testgraph = nx.Graph()
list_of_nodegroups = [a, b, c , d, E]
И вот где это не удается:
## GRAPH construction - adding nodes
for ng1 in list_of_nodegroups1:
testgraph.add_nodes_from(ng1)
Я получаю такую ошибку:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/usr/local/lib/python3.5/dist-packages/networkx/classes/graph.py in add_nodes_from(self, nodes_for_adding, **attr)
535 try:
--> 536 if n not in self._node:
537 self._adj[n] = self.adjlist_inner_dict_factory()
TypeError: unhashable type: 'dict'
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call last)
<ipython-input-10-718f064c86a3> in <module>()
1 for ng1 in list_of_nodegroups:
----> 2 testgraph.add_nodes_from(ng1)
/usr/local/lib/python3.5/dist-packages/networkx/classes/graph.py in add_nodes_from(self, nodes_for_adding, **attr)
540 self._node[n].update(attr)
541 except TypeError:
--> 542 nn, ndict = n
543 if nn not in self._node:
544 self._adj[nn] = self.adjlist_inner_dict_factory()
ValueError: too many values to unpack (expected 2)
Ссылаясь на (насколько я понимаю) 2 вещи:
Я пытаюсь выяснить, как именно это можно решить, будь то в этом коде или где-то еще, и любая помощь очень ценится!
Обновлено:
Моя цель состоит в том, чтобы иметь граф, состоящий из 4 типов «дочерних узлов», являющихся a, b, c, d, и 1 тип «материнских узлов», являющихся E, например:
[ ('E1', {'a0': 0, 'b0': 0, 'c0': 0, 'd0': 0} ),
('E2', {'a1': 1, 'b0': 0, 'c0': 0, 'd0': 0} ),
('E3', {'a1': 1, 'b1': 1, 'c0': 0, 'd0': 0} ),
...
('E625', {'a5': 5, 'b5': 5, 'c5': 5, 'd5': 5} ),
]
Документация для Graph.add_nodes_from(nodes_for_adding, **attr)
: nodes_for_adding
(повторяемый контейнер) - контейнер узлов (список, dict, set и т. д.). ИЛИ Контейнер кортежей (узел, атрибут dict). Атрибуты узла обновляются с помощью атрибута dict.
Каждый элемент в вашем списке E
представляет собой кортеж, содержащий один узел и 4 словаря, в то время как add_nodes_from
принимает только один словарь. Эти 4 дикта должны быть объединены в один диктатор: {'a': i, 'b': j, 'c': k, 'd': l}
.
Также список E
содержит 625 × 5⁴ = 390625 элементов. Это ваше намерение или вы пытаетесь перечислить узел? Если вы хотите перечислить, это не сработает, как вы ожидали. Вместо этого используйте
from itertools import product
E = [('E_%d' % h, {'a': i, 'b': j, 'c': k, 'd': l})
for h, (i, j, k, l) in enumerate(product(range(5), repeat=4), start=1)]
Если вы используете for h in ... for i in ...
таким образом, он создаст список из 390625 элементов, но будет добавлено только 625 узлов. Например, будет два кортежа ('E1', {...})
и ('E1', {...})
, и первый узел, созданный первым кортежом, будет перезаписан вторым кортежем. Вы можете попробовать с меньшими значениями, чтобы увидеть эффект.
Спасибо @ducminh Вы правы насчет того, что dicts должен быть одним (а не 4 отдельными, я упустил это из виду. Моя единственная цель - иметь 4 подтипа узлов, каждый с n вариациями (в этом примере 5). И 5-й Тип "мать", в котором хранятся все возможные комбинации между ними: 5 ^ 4 625. Но я мог заметить это неправильно.