Repository: networkx/networkx

Issue:
Expanded datatypes for graphml writer
The GraphML writer doesn't handle NumPy floats since it only knows to accept Python floats. I'm sure we can make this a bit easier for users.



Discussion:
The writer should work with `numpy.float` variables, since `numpy.float` is just an alias to python's `float` type:

``` python
>>> import numpy as np
>>> x = np.float(32.45)
>>> type(x)
<type 'float'>
```

Are you talking about `float32` and `float64` in numpy? Worth noting that they are single and double precision datatypes respectively.

I don't think the precision matters, since we don't seem to care about the precision when writing regular Python floats to GraphML either.

@chebee7i do you have some ideas for how to approach this? 
Otherwise I'm going to bump it to networkx-2.1
This is still an issue in networkx 2.1.
Yes -- the github issue shows that the milestone was modifed from networkx-2.1 to networkx-2.2.

Would you be willing to try to get that working?  We need a pull request.

Resolving patch:
diff --git a/networkx/readwrite/graphml.py b/networkx/readwrite/graphml.py
--- a/networkx/readwrite/graphml.py
+++ b/networkx/readwrite/graphml.py
@@ -334,6 +334,23 @@ class GraphML(object):
              (float, "float"), (float, "double"),
              (bool, "boolean")]
 
+    # These additions to types allow writing numpy types
+    try:
+        import numpy as np
+    except:
+        pass
+    else:
+        # prepend so that python types are created upon read (last entry wins)
+        types = [(np.float64, "float"), (np.float32, "float"),
+                 (np.float16, "float"), (np.float_, "float"),
+                 (np.int, "int"), (np.int8, "int"),
+                 (np.int16, "int"), (np.int32, "int"),
+                 (np.int64, "int"), (np.uint8, "int"),
+                 (np.uint16, "int"), (np.uint32, "int"),
+                 (np.uint64, "int"), (np.int_, "int"),
+                 (np.intc, "int"), (np.intp, "int"),
+                ] + types
+
     xml_type = dict(types)
     python_type = dict(reversed(a) for a in types)
 


Test patch:
diff --git a/networkx/readwrite/tests/test_graphml.py b/networkx/readwrite/tests/test_graphml.py
--- a/networkx/readwrite/tests/test_graphml.py
+++ b/networkx/readwrite/tests/test_graphml.py
@@ -932,6 +932,58 @@ def test_multigraph_to_graph(self):
         os.close(fd)
         os.unlink(fname)
 
+    def test_numpy_float(self):
+        try:
+            import numpy as np
+        except:
+            return
+        wt = np.float(3.4)
+        G = nx.Graph([(1, 2, {'weight': wt})])
+        fd, fname = tempfile.mkstemp()
+        self.writer(G, fname)
+        H = nx.read_graphml(fname, node_type=int)
+        assert_equal(G._adj, H._adj)
+        os.close(fd)
+        os.unlink(fname)
+
+    def test_numpy_float64(self):
+        try:
+            import numpy as np
+        except:
+            return
+        wt = np.float64(3.4)
+        G = nx.Graph([(1, 2, {'weight': wt})])
+        fd, fname = tempfile.mkstemp()
+        self.writer(G, fname)
+        H = nx.read_graphml(fname, node_type=int)
+        assert_equal(G.edges, H.edges)
+        wtG = G[1][2]['weight']
+        wtH = H[1][2]['weight']
+        assert_almost_equal(wtG, wtH, places=6)
+        assert_equal(type(wtG), np.float64)
+        assert_equal(type(wtH), float)
+        os.close(fd)
+        os.unlink(fname)
+
+    def test_numpy_float32(self):
+        try:
+            import numpy as np
+        except:
+            return
+        wt = np.float32(3.4)
+        G = nx.Graph([(1, 2, {'weight': wt})])
+        fd, fname = tempfile.mkstemp()
+        self.writer(G, fname)
+        H = nx.read_graphml(fname, node_type=int)
+        assert_equal(G.edges, H.edges)
+        wtG = G[1][2]['weight']
+        wtH = H[1][2]['weight']
+        assert_almost_equal(wtG, wtH, places=6)
+        assert_equal(type(wtG), np.float32)
+        assert_equal(type(wtH), float)
+        os.close(fd)
+        os.unlink(fname)
+
     def test_unicode_attributes(self):
         G = nx.Graph()
         try:  # Python 3.x