I' trying to convert a NetwrokX graph into the pyg format to feed it to a GCN.
from_networkx(G) works without problems
from_networkx(G, group_node_attrs=x) # doesn't work, and I get the following error:
Here the documentation about how the function 'from_networkx': https://pytorch-geometric.readthedocs.io/en/latest/_modules/torch_geometric/utils/convert.html
Traceback (most recent call last): File "/home/iris/PycharmProjects/GNN/input_preprocessing.py", line 161, in pyg_graph1 = from_networkx(G1, group_node_attrs=x_1_str) File "/home/iris/venv/GNN/lib/python3.10/site-packages/torch_geometric/utils/convert.py", line 262, in from_networkx x = data[key] File "/home/iris/venv/GNN/lib/python3.10/site-packages/torch_geometric/data/data.py", line 444, in getitem return self._store[key] File "/home/iris/venv/GNN/lib/python3.10/site-packages/torch_geometric/data/storage.py", line 85, in getitem return self._mapping[key] TypeError: unhashable type: 'list'
Here the example (the original x is actually longer, each list consists of the 768 dim, but here is shorter for a general representation):
import networkx as nx
from torch_geometric.utils.convert import from_networkx
from torch_geometric.data import Data
from torch_geometric.loader import DataLoader
nodes= ['1', '5', '28']
edges= [('1', '5'), ('5', '28')]
G = nx.DiGraph()
G.add_nodes_from(nodes)
G.add_edges_from(edges)
x=[['0.7844669818878174', '-0.40328940749168396', '-0.9366764426231384'],['0.14061762392520905', '-1.1449155807495117', '-0.1811756044626236'],['-1.8840126991271973', '-1.2096494436264038', '1.0780194997787476']]
pyg_graph = from_networkx(G, group_node_attrs=x)
The format of my list of features isn't correct, but I don't know which shape it should have to work.
I tried to change the format of the elements elements of the nested list of features from str to int, but it isn't the problem.
Thank you very much in advance!
There are a number of problems here (quote from the docs, # <--- insertions mine):
def from_networkx( G: Any, group_node_attrs: Optional[Union[List[str], all]] = None, group_edge_attrs: Optional[Union[List[str], all]] = None, ) -> 'torch_geometric.data.Data': r"""Converts a :obj:`networkx.Graph` or :obj:`networkx.DiGraph` to a :class:`torch_geometric.data.Data` instance. Args: G (networkx.Graph or networkx.DiGraph): A networkx graph. group_node_attrs (List[str] or all, optional): The node attributes to # <---- (point 1) be concatenated and added to :obj:`data.x`. (default: :obj:`None`) # <---- group_edge_attrs (List[str] or all, optional): The edge attributes to be concatenated and added to :obj:`data.edge_attr`. (default: :obj:`None`) .. note:: All :attr:`group_node_attrs` and :attr:`group_edge_attrs` values must be numeric. # <-- point 2
[...]
To fix these errors I have taken your code and augmented it.
import networkx as nx
from torch_geometric.utils.convert import from_networkx
from torch_geometric.data import Data
from torch_geometric.loader import DataLoader
edges= [('1', '5'), ('5', '28')]
nodes= ['1', '5', '28']
x=[['0.7844669818878174', '-0.40328940749168396', '-0.9366764426231384'],['0.14061762392520905', '-1.1449155807495117', '-0.1811756044626236'],['-1.8840126991271973', '-1.2096494436264038', '1.0780194997787476']]
# make a dedicated node list, which assigns nodes to their attributes
# and ensures proper data types.
node_list = []
for node, features in zip(nodes, x):
node_list.append((node, {str(a):float(b) for a, b in enumerate(features)}))
G = nx.DiGraph()
G.add_nodes_from(node_list) # now the attributes are part of the original nx-graph
G.add_edges_from(edges)
pyg_graph = from_networkx(G, group_node_attrs=['0', '1', '2'])
print(pyg_graph.x)
output:
tensor([[ 0.7845, -0.4033, -0.9367],
[ 0.1406, -1.1449, -0.1812],
[-1.8840, -1.2096, 1.0780]])