def from_networkx(G): 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. """ G = nx.convert_node_labels_to_integers(G) G = G.to_directed() if not nx.is_directed(G) else G edge_index = torch.tensor(list(G.edges)).t().contiguous() data = {} for i, (_, feat_dict) in enumerate(G.nodes(data=True)): for key, value in feat_dict.items(): data[key] = [value] if i == 0 else data[key] + [value] for i, (_, _, feat_dict) in enumerate(G.edges(data=True)): for key, value in feat_dict.items(): data[key] = [value] if i == 0 else data[key] + [value] for key, item in data.items(): try: data[key] = torch.tensor(item) except ValueError: pass data['edge_index'] = edge_index.view(2, -1) data = torch_geometric.data.Data.from_dict(data) data.num_nodes = G.number_of_nodes() return data
def from_networkx(G): r""""Converts a networkx graph to a data object graph. Args: G (networkx.Graph): A networkx graph. """ edge_index = torch.tensor(list(G.edges)).t().contiguous() keys = [] keys += list(G.nodes(data=True)[0].keys()) keys += list(list(G.edges(data=True))[0][2].keys()) data = {key: [] for key in keys} for _, feat_dict in G.nodes(data=True): for key, value in feat_dict.items(): data[key].append(value) for _, _, feat_dict in G.edges(data=True): for key, value in feat_dict.items(): data[key].append(value) for key, item in data.items(): data[key] = torch.tensor(item) data['edge_index'] = edge_index return torch_geometric.data.Data.from_dict(data)
def from_networkx(G): 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. """ G = G.to_directed() if not nx.is_directed(G) else G edge_index = torch.tensor(list(G.edges)).t().contiguous() keys = [] keys += list(list(G.nodes(data=True))[0][1].keys()) keys += list(list(G.edges(data=True))[0][2].keys()) data = {key: [] for key in keys} for _, feat_dict in G.nodes(data=True): for key, value in feat_dict.items(): data[key].append(value) for _, _, feat_dict in G.edges(data=True): for key, value in feat_dict.items(): data[key].append(value) for key, item in data.items(): data[key] = torch.tensor(item) data['edge_index'] = edge_index data = torch_geometric.data.Data.from_dict(data) data.num_nodes = G.number_of_nodes() return data
def from_networkx(G, group_node_attrs: Optional[Union[List[str], all]] = None, group_edge_attrs: Optional[Union[List[str], all]] = None): 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 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. """ import networkx as nx G = nx.convert_node_labels_to_integers(G) G = G.to_directed() if not nx.is_directed(G) else G if isinstance(G, (nx.MultiGraph, nx.MultiDiGraph)): edges = list(G.edges(keys=False)) else: edges = list(G.edges) edge_index = torch.tensor(edges, dtype=torch.long).t().contiguous() data = defaultdict(list) if G.number_of_nodes() > 0: node_attrs = list(next(iter(G.nodes(data=True)))[-1].keys()) else: node_attrs = {} if G.number_of_edges() > 0: edge_attrs = list(next(iter(G.edges(data=True)))[-1].keys()) else: edge_attrs = {} for i, (_, feat_dict) in enumerate(G.nodes(data=True)): if set(feat_dict.keys()) != set(node_attrs): raise ValueError('Not all nodes contain the same attributes') for key, value in feat_dict.items(): data[str(key)].append(value) for i, (_, _, feat_dict) in enumerate(G.edges(data=True)): if set(feat_dict.keys()) != set(edge_attrs): raise ValueError('Not all edges contain the same attributes') for key, value in feat_dict.items(): key = f'edge_{key}' if key in node_attrs else key data[str(key)].append(value) for key, value in data.items(): try: data[key] = torch.tensor(value) except ValueError: pass data['edge_index'] = edge_index.view(2, -1) data = torch_geometric.data.Data.from_dict(data) if group_node_attrs is all: group_node_attrs = list(node_attrs) if group_node_attrs is not None: xs = [] for key in group_node_attrs: x = data[key] x = x.view(-1, 1) if x.dim() <= 1 else x xs.append(x) del data[key] data.x = torch.cat(xs, dim=-1) if group_edge_attrs is all: group_edge_attrs = list(edge_attrs) if group_edge_attrs is not None: xs = [] for key in group_edge_attrs: key = f'edge_{key}' if key in node_attrs else key x = data[key] x = x.view(-1, 1) if x.dim() <= 1 else x xs.append(x) del data[key] data.edge_attr = torch.cat(xs, dim=-1) if data.x is None and data.pos is None: data.num_nodes = G.number_of_nodes() return data