From 8f0341155ede981f4125fcf7ce5a9f448a0b64a3 Mon Sep 17 00:00:00 2001 From: Sultan Orazbayev Date: Mon, 26 Jun 2023 14:56:04 +0600 Subject: [PATCH 1/2] Allow isolate creation during export to networkx. Fixes #475. --- graphblas/io/_networkx.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/graphblas/io/_networkx.py b/graphblas/io/_networkx.py index 2324a11c2..3c62f27f2 100644 --- a/graphblas/io/_networkx.py +++ b/graphblas/io/_networkx.py @@ -31,7 +31,7 @@ def from_networkx(G, nodelist=None, dtype=None, weight="weight", name=None): # TODO: add parameters to allow different networkx classes and attribute names -def to_networkx(m, edge_attribute="weight"): +def to_networkx(m, edge_attribute="weight", create_isolates=False): """Create a networkx DiGraph from a square adjacency Matrix. Parameters @@ -41,6 +41,11 @@ def to_networkx(m, edge_attribute="weight"): edge_attribute : str, optional Name of edge attribute from values of Matrix. If None, values will be skipped. Default is "weight". + create_isolates : bool, optional + If row $i$ and column $i$ are both empty, then node $i$ is an isolate. By default, + these isolate nodes are ignored. If True, then the graph will also contain the + isolate nodes. Note that for very large adjacency matrices, creating isolates + will increase the memory footprint of the graph. Returns ------- @@ -56,4 +61,6 @@ def to_networkx(m, edge_attribute="weight"): G.add_edges_from(zip(rows, cols)) else: G.add_weighted_edges_from(zip(rows, cols, vals.tolist()), weight=edge_attribute) + if create_isolates: + G.add_nodes_from(range(max(m.shape))) return G From 423f82411f7fc4bd244460d8d4b6f895d9c3472b Mon Sep 17 00:00:00 2001 From: Sultan Orazbayev Date: Mon, 26 Jun 2023 15:20:16 +0600 Subject: [PATCH 2/2] Add test for `create_isolates`. --- graphblas/tests/test_io.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/graphblas/tests/test_io.py b/graphblas/tests/test_io.py index 671b12bd6..651fd89f9 100644 --- a/graphblas/tests/test_io.py +++ b/graphblas/tests/test_io.py @@ -161,6 +161,17 @@ def test_matrix_to_from_networkx(): assert M.nvals == 0 assert M.shape == (1, 1) + # test creation of isolates + M = gb.Matrix.from_edgelist([(0,1),(3,0)],nrows=5,ncols=5) + G = gb.io.to_networkx(M, create_isolates=True) + G_nx = nx.DiGraph() + G_nx.add_edges_from([(0,1),(3,0)]) + G_nx.add_nodes_from(range(5)) + assert G.number_of_edges() == G_nx.number_of_edges() == 2 + assert G.number_of_nodes() == G_nx.number_of_nodes() == 5 + from networkx.utils import graphs_equal + assert graphs_equal(G, G_nx) + @pytest.mark.skipif("not ss") @pytest.mark.parametrize("engine", ["auto", "scipy", "fmm"])