Evan_Nt
Evan_Nt

Reputation: 75

how to add duplicate nodes from lists in Networkx

I have 2 lists:

source_nodes = ['A', 'B', 'C', 'D','D']
dest_nodes = ['P', 'P', 'R', 'S', 'S']

I added edges between the lists' elements using MultiGraph() (it didn't work with DiGraph() and I don't know why). What I do is:

for u,v in zip(source_nodes, dest_nodes):
    G.add_edge(u, v)

But when I try to get the nodes it removes the duplicates, I get: ['A', 'B', 'C', 'D','P', 'R', 'S'] instead of ['A', 'B', 'C', 'D','D','P', 'P', 'R', 'S', 'S']

Since I need all of them for later computations, how can I get the expected results?

Upvotes: 1

Views: 1913

Answers (2)

Gambit1614
Gambit1614

Reputation: 8811

My assumptions based on your question description:

  • You want to retain all the duplicate nodes
  • You want to treat the duplicate nodes as unique nodes, i.e. if nodes are [A, A, B, C], then even though the first and second nodes have same name A, they are to be treated as if they are separate nodes, like A_1 and A_2for your later computation.

As other answers have pointed out, you can't use duplicate nodes directly in your graph.

However, if you still want to treat the duplicate entries as separate nodes, you can assign unique IDs to each node, and then add them to the graph. Just remember to store the mapping somewhere, so that you can use it later, to extract the original name for say drawing nodes, etc.

import networkx as nx
import uuid

source_nodes = ['A', 'B', 'C', 'D','D']
dest_nodes = ['P', 'P', 'R', 'S', 'S']

def update_mapping(uuid_mapping, node_list):
    # This will contain the unique IDs of the nodes
    unique_node_list = []
    for node in node_list:
        # Create unique ID for node
        unique_name = uuid.uuid4()

        # Add the unique ID to the list
        unique_node_list.append(unique_name)

        # Update the mapping
        uuid_mapping[unique_name]=node
    return unique_node_list

# The key is the new unique ID, while the value is the old value
uuid_mapping = {}

# Since dictionaries are mutable in Python, you don't need to
# return and assign them explicitly.
new_source_nodes = update_mapping(uuid_mapping, source_nodes)
new_dest_nodes = update_mapping(uuid_mapping, dest_nodes)

You can check out the unique mapping for each node, just to verify .

print(uuid_mapping)

# {UUID('0bea8e06-51cc-4a22-b0f3-5e7e8884c2f6'): 'A',
# UUID('1a0799aa-d895-4e09-92ac-6fc21a68e2bb'): 'P',
# UUID('334f0bff-c56c-4717-8582-6226a9a0bfb1'): 'C',
# UUID('5727aa18-ae11-4554-bbe9-31b8c0d1f114'): 'P',
# UUID('62155bac-f47f-4b4d-83c7-efd5a27d5f8d'): 'R',
# UUID('acff9155-c2c7-4889-a7f2-dd795b16784a'): 'S',
# UUID('b62324c3-a918-410b-9cae-4d1f87044a88'): 'D',
# UUID('b64eb741-68a2-4082-b68a-bce1150de9dd'): 'D',
# UUID('ba3998fd-3227-44fe-990e-dd3e1bcee259'): 'B',
# UUID('ede62a20-a391-4303-8648-0650f0a3a149'): 'S'}

Notice there are 2 keys with values as D, S, and P. Now you can use the new_source_nodes and new_dest_nodes to create a graph

G = nx.DiGraph()

for u,v in zip(new_source_nodes, new_dest_nodes):
    G.add_edge(u, v)

Then, suppose you want to visualize the graph, pass the uuid_mapping dict as labels for nodes

pos = nx.spring_layout(G)
nx.draw(G, pos=pos,labels=uuid_mapping)

Graph with duplicate node labels

You can view the working code on Google Colab Notebook here.

References:

Upvotes: 0

sxeros
sxeros

Reputation: 672

It is not possible to have the same Note multiple times. But when you implement your Graph with G = networkx.MultiGraph() you will automatically get all edges, already including the duplicate edges. So you get only 1 D and 1 S, but they will be connected with 2 edges

Code:

G = nx.MultiGraph()

source_nodes = ['A', 'B', 'C', 'D','D']
dest_nodes = ['P', 'P', 'R', 'S', 'S']

for u,v in zip(source_nodes, dest_nodes):
    G.add_edge(u, v)


for i in G.nodes:
    print(i, G.edges(i))

Output:

A -> [('A', 'P')]

P -> [('P', 'A'), ('P', 'B')]

B -> [('B', 'P')]

C -> [('C', 'R')]

R -> [('R', 'C')]

D -> [('D', 'S'), ('D', 'S')]

S -> [('S', 'D'), ('S', 'D')]

Upvotes: 1

Related Questions