comparison env/lib/python3.9/site-packages/networkx/tests/test_convert_numpy.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 import pytest
2
3 np = pytest.importorskip("numpy")
4 np_assert_equal = np.testing.assert_equal
5
6 import networkx as nx
7 from networkx.generators.classic import barbell_graph, cycle_graph, path_graph
8 from networkx.testing.utils import assert_graphs_equal
9
10
11 class TestConvertNumpy:
12 def setup_method(self):
13 self.G1 = barbell_graph(10, 3)
14 self.G2 = cycle_graph(10, create_using=nx.DiGraph)
15
16 self.G3 = self.create_weighted(nx.Graph())
17 self.G4 = self.create_weighted(nx.DiGraph())
18
19 def test_exceptions(self):
20 G = np.array("a")
21 pytest.raises(nx.NetworkXError, nx.to_networkx_graph, G)
22
23 def create_weighted(self, G):
24 g = cycle_graph(4)
25 G.add_nodes_from(g)
26 G.add_weighted_edges_from((u, v, 10 + u) for u, v in g.edges())
27 return G
28
29 def assert_equal(self, G1, G2):
30 assert sorted(G1.nodes()) == sorted(G2.nodes())
31 assert sorted(G1.edges()) == sorted(G2.edges())
32
33 def identity_conversion(self, G, A, create_using):
34 assert A.sum() > 0
35 GG = nx.from_numpy_matrix(A, create_using=create_using)
36 self.assert_equal(G, GG)
37 GW = nx.to_networkx_graph(A, create_using=create_using)
38 self.assert_equal(G, GW)
39 GI = nx.empty_graph(0, create_using).__class__(A)
40 self.assert_equal(G, GI)
41
42 def test_shape(self):
43 "Conversion from non-square array."
44 A = np.array([[1, 2, 3], [4, 5, 6]])
45 pytest.raises(nx.NetworkXError, nx.from_numpy_matrix, A)
46
47 def test_identity_graph_matrix(self):
48 "Conversion from graph to matrix to graph."
49 A = nx.to_numpy_matrix(self.G1)
50 self.identity_conversion(self.G1, A, nx.Graph())
51
52 def test_identity_graph_array(self):
53 "Conversion from graph to array to graph."
54 A = nx.to_numpy_matrix(self.G1)
55 A = np.asarray(A)
56 self.identity_conversion(self.G1, A, nx.Graph())
57
58 def test_identity_digraph_matrix(self):
59 """Conversion from digraph to matrix to digraph."""
60 A = nx.to_numpy_matrix(self.G2)
61 self.identity_conversion(self.G2, A, nx.DiGraph())
62
63 def test_identity_digraph_array(self):
64 """Conversion from digraph to array to digraph."""
65 A = nx.to_numpy_matrix(self.G2)
66 A = np.asarray(A)
67 self.identity_conversion(self.G2, A, nx.DiGraph())
68
69 def test_identity_weighted_graph_matrix(self):
70 """Conversion from weighted graph to matrix to weighted graph."""
71 A = nx.to_numpy_matrix(self.G3)
72 self.identity_conversion(self.G3, A, nx.Graph())
73
74 def test_identity_weighted_graph_array(self):
75 """Conversion from weighted graph to array to weighted graph."""
76 A = nx.to_numpy_matrix(self.G3)
77 A = np.asarray(A)
78 self.identity_conversion(self.G3, A, nx.Graph())
79
80 def test_identity_weighted_digraph_matrix(self):
81 """Conversion from weighted digraph to matrix to weighted digraph."""
82 A = nx.to_numpy_matrix(self.G4)
83 self.identity_conversion(self.G4, A, nx.DiGraph())
84
85 def test_identity_weighted_digraph_array(self):
86 """Conversion from weighted digraph to array to weighted digraph."""
87 A = nx.to_numpy_matrix(self.G4)
88 A = np.asarray(A)
89 self.identity_conversion(self.G4, A, nx.DiGraph())
90
91 def test_nodelist(self):
92 """Conversion from graph to matrix to graph with nodelist."""
93 P4 = path_graph(4)
94 P3 = path_graph(3)
95 nodelist = list(P3)
96 A = nx.to_numpy_matrix(P4, nodelist=nodelist)
97 GA = nx.Graph(A)
98 self.assert_equal(GA, P3)
99
100 # Make nodelist ambiguous by containing duplicates.
101 nodelist += [nodelist[0]]
102 pytest.raises(nx.NetworkXError, nx.to_numpy_matrix, P3, nodelist=nodelist)
103
104 def test_weight_keyword(self):
105 WP4 = nx.Graph()
106 WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3)) for n in range(3))
107 P4 = path_graph(4)
108 A = nx.to_numpy_matrix(P4)
109 np_assert_equal(A, nx.to_numpy_matrix(WP4, weight=None))
110 np_assert_equal(0.5 * A, nx.to_numpy_matrix(WP4))
111 np_assert_equal(0.3 * A, nx.to_numpy_matrix(WP4, weight="other"))
112
113 def test_from_numpy_matrix_type(self):
114 A = np.matrix([[1]])
115 G = nx.from_numpy_matrix(A)
116 assert type(G[0][0]["weight"]) == int
117
118 A = np.matrix([[1]]).astype(np.float)
119 G = nx.from_numpy_matrix(A)
120 assert type(G[0][0]["weight"]) == float
121
122 A = np.matrix([[1]]).astype(np.str)
123 G = nx.from_numpy_matrix(A)
124 assert type(G[0][0]["weight"]) == str
125
126 A = np.matrix([[1]]).astype(np.bool)
127 G = nx.from_numpy_matrix(A)
128 assert type(G[0][0]["weight"]) == bool
129
130 A = np.matrix([[1]]).astype(np.complex)
131 G = nx.from_numpy_matrix(A)
132 assert type(G[0][0]["weight"]) == complex
133
134 A = np.matrix([[1]]).astype(np.object)
135 pytest.raises(TypeError, nx.from_numpy_matrix, A)
136
137 G = nx.cycle_graph(3)
138 A = nx.adj_matrix(G).todense()
139 H = nx.from_numpy_matrix(A)
140 assert all(type(m) == int and type(n) == int for m, n in H.edges())
141 H = nx.from_numpy_array(A)
142 assert all(type(m) == int and type(n) == int for m, n in H.edges())
143
144 def test_from_numpy_matrix_dtype(self):
145 dt = [("weight", float), ("cost", int)]
146 A = np.matrix([[(1.0, 2)]], dtype=dt)
147 G = nx.from_numpy_matrix(A)
148 assert type(G[0][0]["weight"]) == float
149 assert type(G[0][0]["cost"]) == int
150 assert G[0][0]["cost"] == 2
151 assert G[0][0]["weight"] == 1.0
152
153 def test_to_numpy_recarray(self):
154 G = nx.Graph()
155 G.add_edge(1, 2, weight=7.0, cost=5)
156 A = nx.to_numpy_recarray(G, dtype=[("weight", float), ("cost", int)])
157 assert sorted(A.dtype.names) == ["cost", "weight"]
158 assert A.weight[0, 1] == 7.0
159 assert A.weight[0, 0] == 0.0
160 assert A.cost[0, 1] == 5
161 assert A.cost[0, 0] == 0
162
163 def test_numpy_multigraph(self):
164 G = nx.MultiGraph()
165 G.add_edge(1, 2, weight=7)
166 G.add_edge(1, 2, weight=70)
167 A = nx.to_numpy_matrix(G)
168 assert A[1, 0] == 77
169 A = nx.to_numpy_matrix(G, multigraph_weight=min)
170 assert A[1, 0] == 7
171 A = nx.to_numpy_matrix(G, multigraph_weight=max)
172 assert A[1, 0] == 70
173
174 def test_from_numpy_matrix_parallel_edges(self):
175 """Tests that the :func:`networkx.from_numpy_matrix` function
176 interprets integer weights as the number of parallel edges when
177 creating a multigraph.
178
179 """
180 A = np.matrix([[1, 1], [1, 2]])
181 # First, with a simple graph, each integer entry in the adjacency
182 # matrix is interpreted as the weight of a single edge in the graph.
183 expected = nx.DiGraph()
184 edges = [(0, 0), (0, 1), (1, 0)]
185 expected.add_weighted_edges_from([(u, v, 1) for (u, v) in edges])
186 expected.add_edge(1, 1, weight=2)
187 actual = nx.from_numpy_matrix(A, parallel_edges=True, create_using=nx.DiGraph)
188 assert_graphs_equal(actual, expected)
189 actual = nx.from_numpy_matrix(A, parallel_edges=False, create_using=nx.DiGraph)
190 assert_graphs_equal(actual, expected)
191 # Now each integer entry in the adjacency matrix is interpreted as the
192 # number of parallel edges in the graph if the appropriate keyword
193 # argument is specified.
194 edges = [(0, 0), (0, 1), (1, 0), (1, 1), (1, 1)]
195 expected = nx.MultiDiGraph()
196 expected.add_weighted_edges_from([(u, v, 1) for (u, v) in edges])
197 actual = nx.from_numpy_matrix(
198 A, parallel_edges=True, create_using=nx.MultiDiGraph
199 )
200 assert_graphs_equal(actual, expected)
201 expected = nx.MultiDiGraph()
202 expected.add_edges_from(set(edges), weight=1)
203 # The sole self-loop (edge 0) on vertex 1 should have weight 2.
204 expected[1][1][0]["weight"] = 2
205 actual = nx.from_numpy_matrix(
206 A, parallel_edges=False, create_using=nx.MultiDiGraph
207 )
208 assert_graphs_equal(actual, expected)
209
210 def test_symmetric(self):
211 """Tests that a symmetric matrix has edges added only once to an
212 undirected multigraph when using :func:`networkx.from_numpy_matrix`.
213
214 """
215 A = np.matrix([[0, 1], [1, 0]])
216 G = nx.from_numpy_matrix(A, create_using=nx.MultiGraph)
217 expected = nx.MultiGraph()
218 expected.add_edge(0, 1, weight=1)
219 assert_graphs_equal(G, expected)
220
221 def test_dtype_int_graph(self):
222 """Test that setting dtype int actually gives an integer matrix.
223
224 For more information, see GitHub pull request #1363.
225
226 """
227 G = nx.complete_graph(3)
228 A = nx.to_numpy_matrix(G, dtype=int)
229 assert A.dtype == int
230
231 def test_dtype_int_multigraph(self):
232 """Test that setting dtype int actually gives an integer matrix.
233
234 For more information, see GitHub pull request #1363.
235
236 """
237 G = nx.MultiGraph(nx.complete_graph(3))
238 A = nx.to_numpy_matrix(G, dtype=int)
239 assert A.dtype == int
240
241
242 class TestConvertNumpyArray:
243 def setup_method(self):
244 self.G1 = barbell_graph(10, 3)
245 self.G2 = cycle_graph(10, create_using=nx.DiGraph)
246 self.G3 = self.create_weighted(nx.Graph())
247 self.G4 = self.create_weighted(nx.DiGraph())
248
249 def create_weighted(self, G):
250 g = cycle_graph(4)
251 G.add_nodes_from(g)
252 G.add_weighted_edges_from((u, v, 10 + u) for u, v in g.edges())
253 return G
254
255 def assert_equal(self, G1, G2):
256 assert sorted(G1.nodes()) == sorted(G2.nodes())
257 assert sorted(G1.edges()) == sorted(G2.edges())
258
259 def identity_conversion(self, G, A, create_using):
260 assert A.sum() > 0
261 GG = nx.from_numpy_array(A, create_using=create_using)
262 self.assert_equal(G, GG)
263 GW = nx.to_networkx_graph(A, create_using=create_using)
264 self.assert_equal(G, GW)
265 GI = nx.empty_graph(0, create_using).__class__(A)
266 self.assert_equal(G, GI)
267
268 def test_shape(self):
269 "Conversion from non-square array."
270 A = np.array([[1, 2, 3], [4, 5, 6]])
271 pytest.raises(nx.NetworkXError, nx.from_numpy_array, A)
272
273 def test_identity_graph_array(self):
274 "Conversion from graph to array to graph."
275 A = nx.to_numpy_array(self.G1)
276 self.identity_conversion(self.G1, A, nx.Graph())
277
278 def test_identity_digraph_array(self):
279 """Conversion from digraph to array to digraph."""
280 A = nx.to_numpy_array(self.G2)
281 self.identity_conversion(self.G2, A, nx.DiGraph())
282
283 def test_identity_weighted_graph_array(self):
284 """Conversion from weighted graph to array to weighted graph."""
285 A = nx.to_numpy_array(self.G3)
286 self.identity_conversion(self.G3, A, nx.Graph())
287
288 def test_identity_weighted_digraph_array(self):
289 """Conversion from weighted digraph to array to weighted digraph."""
290 A = nx.to_numpy_array(self.G4)
291 self.identity_conversion(self.G4, A, nx.DiGraph())
292
293 def test_nodelist(self):
294 """Conversion from graph to array to graph with nodelist."""
295 P4 = path_graph(4)
296 P3 = path_graph(3)
297 nodelist = list(P3)
298 A = nx.to_numpy_array(P4, nodelist=nodelist)
299 GA = nx.Graph(A)
300 self.assert_equal(GA, P3)
301
302 # Make nodelist ambiguous by containing duplicates.
303 nodelist += [nodelist[0]]
304 pytest.raises(nx.NetworkXError, nx.to_numpy_array, P3, nodelist=nodelist)
305
306 def test_weight_keyword(self):
307 WP4 = nx.Graph()
308 WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3)) for n in range(3))
309 P4 = path_graph(4)
310 A = nx.to_numpy_array(P4)
311 np_assert_equal(A, nx.to_numpy_array(WP4, weight=None))
312 np_assert_equal(0.5 * A, nx.to_numpy_array(WP4))
313 np_assert_equal(0.3 * A, nx.to_numpy_array(WP4, weight="other"))
314
315 def test_from_numpy_array_type(self):
316 A = np.array([[1]])
317 G = nx.from_numpy_array(A)
318 assert type(G[0][0]["weight"]) == int
319
320 A = np.array([[1]]).astype(np.float)
321 G = nx.from_numpy_array(A)
322 assert type(G[0][0]["weight"]) == float
323
324 A = np.array([[1]]).astype(np.str)
325 G = nx.from_numpy_array(A)
326 assert type(G[0][0]["weight"]) == str
327
328 A = np.array([[1]]).astype(np.bool)
329 G = nx.from_numpy_array(A)
330 assert type(G[0][0]["weight"]) == bool
331
332 A = np.array([[1]]).astype(np.complex)
333 G = nx.from_numpy_array(A)
334 assert type(G[0][0]["weight"]) == complex
335
336 A = np.array([[1]]).astype(np.object)
337 pytest.raises(TypeError, nx.from_numpy_array, A)
338
339 def test_from_numpy_array_dtype(self):
340 dt = [("weight", float), ("cost", int)]
341 A = np.array([[(1.0, 2)]], dtype=dt)
342 G = nx.from_numpy_array(A)
343 assert type(G[0][0]["weight"]) == float
344 assert type(G[0][0]["cost"]) == int
345 assert G[0][0]["cost"] == 2
346 assert G[0][0]["weight"] == 1.0
347
348 def test_to_numpy_recarray(self):
349 G = nx.Graph()
350 G.add_edge(1, 2, weight=7.0, cost=5)
351 A = nx.to_numpy_recarray(G, dtype=[("weight", float), ("cost", int)])
352 assert sorted(A.dtype.names) == ["cost", "weight"]
353 assert A.weight[0, 1] == 7.0
354 assert A.weight[0, 0] == 0.0
355 assert A.cost[0, 1] == 5
356 assert A.cost[0, 0] == 0
357
358 def test_numpy_multigraph(self):
359 G = nx.MultiGraph()
360 G.add_edge(1, 2, weight=7)
361 G.add_edge(1, 2, weight=70)
362 A = nx.to_numpy_array(G)
363 assert A[1, 0] == 77
364 A = nx.to_numpy_array(G, multigraph_weight=min)
365 assert A[1, 0] == 7
366 A = nx.to_numpy_array(G, multigraph_weight=max)
367 assert A[1, 0] == 70
368
369 def test_from_numpy_array_parallel_edges(self):
370 """Tests that the :func:`networkx.from_numpy_array` function
371 interprets integer weights as the number of parallel edges when
372 creating a multigraph.
373
374 """
375 A = np.array([[1, 1], [1, 2]])
376 # First, with a simple graph, each integer entry in the adjacency
377 # matrix is interpreted as the weight of a single edge in the graph.
378 expected = nx.DiGraph()
379 edges = [(0, 0), (0, 1), (1, 0)]
380 expected.add_weighted_edges_from([(u, v, 1) for (u, v) in edges])
381 expected.add_edge(1, 1, weight=2)
382 actual = nx.from_numpy_array(A, parallel_edges=True, create_using=nx.DiGraph)
383 assert_graphs_equal(actual, expected)
384 actual = nx.from_numpy_array(A, parallel_edges=False, create_using=nx.DiGraph)
385 assert_graphs_equal(actual, expected)
386 # Now each integer entry in the adjacency matrix is interpreted as the
387 # number of parallel edges in the graph if the appropriate keyword
388 # argument is specified.
389 edges = [(0, 0), (0, 1), (1, 0), (1, 1), (1, 1)]
390 expected = nx.MultiDiGraph()
391 expected.add_weighted_edges_from([(u, v, 1) for (u, v) in edges])
392 actual = nx.from_numpy_array(
393 A, parallel_edges=True, create_using=nx.MultiDiGraph
394 )
395 assert_graphs_equal(actual, expected)
396 expected = nx.MultiDiGraph()
397 expected.add_edges_from(set(edges), weight=1)
398 # The sole self-loop (edge 0) on vertex 1 should have weight 2.
399 expected[1][1][0]["weight"] = 2
400 actual = nx.from_numpy_array(
401 A, parallel_edges=False, create_using=nx.MultiDiGraph
402 )
403 assert_graphs_equal(actual, expected)
404
405 def test_symmetric(self):
406 """Tests that a symmetric array has edges added only once to an
407 undirected multigraph when using :func:`networkx.from_numpy_array`.
408
409 """
410 A = np.array([[0, 1], [1, 0]])
411 G = nx.from_numpy_array(A, create_using=nx.MultiGraph)
412 expected = nx.MultiGraph()
413 expected.add_edge(0, 1, weight=1)
414 assert_graphs_equal(G, expected)
415
416 def test_dtype_int_graph(self):
417 """Test that setting dtype int actually gives an integer array.
418
419 For more information, see GitHub pull request #1363.
420
421 """
422 G = nx.complete_graph(3)
423 A = nx.to_numpy_array(G, dtype=int)
424 assert A.dtype == int
425
426 def test_dtype_int_multigraph(self):
427 """Test that setting dtype int actually gives an integer array.
428
429 For more information, see GitHub pull request #1363.
430
431 """
432 G = nx.MultiGraph(nx.complete_graph(3))
433 A = nx.to_numpy_array(G, dtype=int)
434 assert A.dtype == int