Stephen
Stephen

Reputation: 1

Python NetworkX converting Panda's ints to floats

I am trying to build networkx diagrams from a pandas dataframe, with a position array for nodes when drawing. The issue that I am having is when including pandas columns as edge attributes. If the attribute column is type float, it will convert the value of node ids (int) into float types, which then causes issues for indexing within the position array for networkx's draw functions.

This could probably be fixed by explicitly adding the attributes after the nodes and edges are created, but I feel like there should be a way for this to work, so I'm missing something obvious.

Thanks for your help.

import networkx as nx
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

#set up datae frame
UpNodes  =np.array([0,0,1,1,2,2,6,6,8,8,10], dtype=np.int)
DownNodes=np.array([1,2,3,4,4,5,7,8,9,10,11], dtype=np.int)
ORDER    =np.array([2,1,1,1,3,2,1,1,1,2,3],dtype=np.float) #toggle this from int to float

df=pd.DataFrame(
{'UpNodes': UpNodes,
 'DownNodes':DownNodes,
 'ORDER': ORDER},
 columns=['UpNodes','DownNodes','ORDER'])

#create array of spatial positions for nodes
pos=np.array(
[[ 0., 0.  ],
 [ 1., 0.5 ],
 [ 1., -0.5 ],
 [ 2., 1.  ],
 [ 2., 0.25],
 [ 2., -1.  ],
 [ 3., 2.  ],
 [ 4., 3.  ],
 [ 4., 1.  ],
 [ 5., 2.  ],
 [ 5., 0.  ],
 [ 6., 0.  ]]
)

plt.figure('Im a plot')

print df
print df.dtypes
G=nx.from_pandas_edgelist(df,'UpNodes','DownNodes','ORDER')
print G.edges

nx.draw(G, pos, node_size=90, with_labels=False)

print 'Done'

plt.show()

Upvotes: 0

Views: 427

Answers (1)

Stephen
Stephen

Reputation: 1

Ok yup it really helps to read the documentation, as this issue was right there. for anyone else who wants to get around this you can just write your own to use itertuples instead of iterrows, which doesn't conserve dtype.

def pandas_to_Network(df,UpNode,DownNode,Attributes):
    #Create a graph
    G=nx.Graph()
    #Loop through the pandas dataframe and add edges
    for row in df.itertuples():
        #convert edge attributes to dictionary form
        edgedata={}
        for edge_key in Attributes:
            edgedata.update({edge_key:getattr(row,edge_key)})

        #create edge
        G.add_edge(getattr(row,UpNode), getattr(row,DownNode),**edgedata)

    return G

Where attributes is a list of column titles (in my case just ['ORDER'])

Upvotes: 0

Related Questions