Search code examples
pythonnumpynetworkxgraphml

Exporting NetworkX graph as graphml throws exception due to numpy.float64 value


I'm analyzing a weighted chemical reaction network using the following code:

import networkx as nx
import pandas as pd

edge_data = pd.read_table('VULCAN 800.dat', sep=',')
edge_list=[]
edge_data = edge_data.fillna(value=0.1)
col1=edge_data['Column_1']
col2=edge_data['Column_2']
col3=edge_data['Column_3']
col4=edge_data['Column_4']
col5=edge_data['Column_5']
col6=edge_data['Column_6']
for i in range(1,560):
    edge_list.append((col1.iloc[i],col2.iloc[i],col5.iloc[i]))
if pd.isnull(col3.iloc[i]) != True:
    edge_list.append((col1.iloc[i],col3.iloc[i],col5.iloc[i]))
    edge_list.append((col2.iloc[i],col3.iloc[i],col5.iloc[i]))
if pd.isnull(col4.iloc[i]) != True:
    edge_list.append((col1.iloc[i],col4.iloc[i],col5.iloc[i]))
    edge_list.append((col2.iloc[i],col4.iloc[i],col5.iloc[i]))
if pd.isnull(col3.iloc[i]) != True and pd.isnull(col4.iloc[i]) != True:
    edge_list.append((col3.iloc[i],col4.iloc[i],col5.iloc[i]))

G=nx.Graph()
G.add_weighted_edges_from(edge_list)
G.remove_node(0.1)
nx.write_graphml(G, '/home/tessa/Git/Network_biosignatures/VULCAN 800k.graphml')

I'd like to export the resulting graph as a graphml file so I can visualize it in Cytoscape, but for some reason, it's throwing the error message:

Traceback (most recent call last):
 File "topo_measure_pn_hot jupiter_weighted.py", line 196, in <module>
nx.write_graphml(G, '/home/tessa/Git/Network_biosignatures/VULCAN 800k.graphml')
 File "<decorator-gen-202>", line 2, in write_graphml
 File "/usr/lib/python2.7/dist-packages/networkx/utils/decorators.py",      line 220, in _open_file
 result = func(*new_args, **kwargs)
 File "/usr/lib/python2.7/dist-packages/networkx/readwrite/graphml.py", line 82, in write_graphml
 writer.add_graph_element(G)
 File "/usr/lib/python2.7/dist-packages/networkx/readwrite/graphml.py", line 351, in add_graph_element
 self.add_edges(G,graph_element)
 File "/usr/lib/python2.7/dist-packages/networkx/readwrite/graphml.py", line 325, in add_edges
 self.add_attributes("edge", edge_element, data, default)
 File "/usr/lib/python2.7/dist-packages/networkx/readwrite/graphml.py", line 300, in add_attributes
 scope=scope, default=default_value)
 File "/usr/lib/python2.7/dist-packages/networkx/readwrite/graphml.py", line 288, in add_data
 '%s as data values.'%element_type)
 networkx.exception.NetworkXError: GraphML writer does not support <type 'numpy.float64'> as data values.

Obviously, the graphml writer doesn't cope well with anything beyond simple attributes for graphs, and I'm guessing its the weight that is throwing the error. However, I'm not sure where the weight value is getting assigned as numpy.float64, or how to strip it of this assignment.

The data that's being read in is formatted like this:

1,H,H2O,OH,H2,1.75116588E-16,,,,,,,,,,,,,,,,,,,,,,,,,,,
2,H,H2O,OH,H2,4.00975292E-13,,,,,,,,,,,,,,,,,,,,,,,,,,,
3,O,H2,OH,H,9.25180896E-14,,,,,,,,,,,,,,,,,,,,,,,,,,,
4,O,H2,OH,H,1.04176774E-13,,,,,,,,,,,,,,,,,,,,,,,,,,,
5,O,H2O,OH,OH,1.04560994E-15,,,,,,,,,,,,,,,,,,,,,,,,,,,
6,O,H2O,OH,OH,2.6959031E-12,,,,,,,,,,,,,,,,,,,,,,,,,,,

Any and all advice is appreciated. Thanks!


Solution

  • This appears to be a bug in networkx. Casting to basic python types solves the issue.

    import numpy as np
    import networkx as nx
    
    total_nodes = 20
    nodes = range(total_nodes)
    
    p = 0.1
    total_edges = int(p * total_nodes ** 2 )
    sources = np.random.choice(nodes, total_edges)
    targets = np.random.choice(nodes, total_edges)
    weights = np.random.rand(total_edges)
    
    # edge_list = zip(sources, targets, weights) # doesn't work
    edge_list = [(int(s), int(t), float(w)) for s, t, w in zip(sources, targets, weights)] # works
    
    G = nx.Graph()
    G.add_weighted_edges_from(edge_list)
    nx.write_graphml(G, 'test.graphml')
    

    EDIT:

    Apparently, they are well aware of the issue (https://github.com/networkx/networkx/issues/1556) but haven't fixed it yet.