So, i want to create weighted graph with data in list of set like this :
temp_comb_test = [{'AN', 'TA'}, {'TA', 'DP'},{'AS','TA'},{'HS','AS'},{'HS','TA'},{'TA','AA'},{'LS','TA'}]
Those weighted, is generate from duplicate edges. Using set()
type of data is simply because in set, (A, B) and (B, A) is equal/duplicate data (in my knowledge list and tuple can't do that). So i wrote a code like this to add weighted edges :
G_Author = nx.Graph()
temp = [] # to keep temporary relation (no dupe)
for iter1 in temp_comb_test:
if len(temp) == 0: # to add first set
temp.append(iter1)
G_Author.add_edges_from([iter1], weight = 1)
print("A - Data ", iter1, " In")
print("temp :", temp)
print(G_Author.edges.data(), '\n')
else:
for iter2 in temp: # iterate temporary list
if iter1 == iter2: # checking duplicate set
nod1, nod2 = iter1
nod3, nod4 = iter2
if ((nod1 == nod3) and (nod2 == nod4) and (nod1 != nod4)): # if set look like --> (A, B) == (A, B)
print("F -", "new :", iter1, "old :", iter2)
wei = nx.get_edge_attributes(G_Author, "weight")
wei2 = wei[nod4, nod3] + 1 # ====> THE PROBLEM 2
nx.set_edge_attributes(G_Author, {(nod3, nod4): {"weight": wei2}})
print(G_Author.edges.data(), '\n')
elif ((nod1 != nod3) and (nod2 != nod4) and (nod1 == nod4)): # if duplicate set looks like --> (A, B) == (B, A)
print("F -", iter1, iter2)
wei3 = nx.get_edge_attributes(G_Author, "weight")
wei4 = wei3[nod3, nod4] + 1
nx.set_edge_attributes(G_Author, {(nod2, nod1): {"weight": wei4}})
else:
nd1, nd2 = iter1
print("E - Data {", nd1, ",", nd2, "} in || iter1 :", iter1)
G_Author.add_edge(nd2, nd1, weight = 1) # ====> THE PROBLEM 1
temp.append({nd2, nd1})
print("temp :", temp)
print(G_Author.edges.data(), '\n')
When i run this code, first element is successfully add to graph. Following by the first else
condition. But, the problem occur on the next iteration like this :
A - Data {'TA', 'AN'} in
temp : [{'TA', 'AN'}]
[('TA', 'AN', {'weight': 1})]
E - Data { DP , TA } in || iter1 : {'DP', 'TA'}
temp : [{'TA', 'AN'}, {'DP', 'TA'}]
[('TA', 'AN', {'weight': 1}), ('TA', 'DP', {'weight': 1})]
F - new : {'DP', 'TA'} old : {'DP', 'TA'}
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-136-f103fe75d64d> in <module>
33 wei = nx.get_edge_attributes(G_Author, "weight")
34 # print(wei)
---> 35 wei2 = wei[nod3, nod4] + 1
36 nx.set_edge_attributes(G_Author, {(nod3, nod4): {"weight": wei2}})
37 print(G_Author.edges.data(), '\n')
KeyError: ('DP', 'TA')
The main error come from this line wei2 = wei[nod4, nod3] + 1
, it is cause by else condition. Where new data is { DP , TA }
, proven by temp : [{'TA', 'AN'}, {'DP', 'TA'}]
. But, when {'DP', 'TA'}
add into the G_Author
, the order is switched and become {'TA', 'DP'}
.
I already try to change wei2 = wei[nod4, nod3] + 1
into wei2 = wei[nod3, nod4] + 1
, but it only fix the first duplicate. When another duplicate comes up, the error come again from those 2 line of code.
Maybe someone can help me with this or have a better solution to generate weight from duplicate set()?
You might want to use collections.Counter
, which will count the occurrences of specific keys in an iterable:
from collections import Counter
from networkx import Graph
# create edge counts
t = [{'A', 'B'}, {'C', 'D'}, {'B', 'A'}]
# note that Counter does not use sets, so change data to tuples
c = Counter(map(tuple,t))
print(c)
# Counter({('A', 'B'): 2, ('C', 'D'): 1})
# add edges to the graph
G = Graph()
for (source, target), weight in c.items():
G.add_edge(source, target, weight=weight)
print(G.edges(data=True))
# [('A', 'B', {'weight': 2}), ('C', 'D', {'weight': 1})]