Reputation: 1559
I have a dataframe like the following:
X Y
0 1 1
1 1 2
2 2 1
3 2 3
4 3 3
I want to create an undirected graph in networkx where each row of the dataframe corresponds to a node in the graph (the name of each node should be the index value of the dataframe), and an edge is drawn between nodes if the two nodes share either the same X or Y values. How can this be done?
Upvotes: 5
Views: 6552
Reputation: 10580
You can define your edges by defining all pairs of nodes that have to same value for 'X'
and the same value for 'Y'
using itertools.combinations
.
import itertools.combinations as comb
edges = set()
for col in df:
for _, data in df.groupby(col):
edges.update(comb(data.index, 2))
G = nx.Graph()
G.add_nodes_from(df.index)
G.add_edges_from(edges)
Upvotes: 3
Reputation: 153460
IIUC:
Your indexes are the labels for your nodes. So, we need to to reshape dataframe a bit to create an edge list dataframe:
d1 = df.reset_index().set_index(['X',df.groupby('X').cumcount()]).unstack()['index']
d2 = df.reset_index().set_index(['Y',df.groupby('Y').cumcount()]).unstack()['index']
d3 = pd.concat([d1,d2]).set_axis(['source','target'], inplace=False, axis=1).dropna().astype(int)
G = nx.from_pandas_edgelist(d3, source='source', target='target')
nx.draw_networkx(G)
Output:
Upvotes: 1