Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/networkx/readwrite/edgelist.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 """ | |
2 ********** | |
3 Edge Lists | |
4 ********** | |
5 Read and write NetworkX graphs as edge lists. | |
6 | |
7 The multi-line adjacency list format is useful for graphs with nodes | |
8 that can be meaningfully represented as strings. With the edgelist | |
9 format simple edge data can be stored but node or graph data is not. | |
10 There is no way of representing isolated nodes unless the node has a | |
11 self-loop edge. | |
12 | |
13 Format | |
14 ------ | |
15 You can read or write three formats of edge lists with these functions. | |
16 | |
17 Node pairs with no data:: | |
18 | |
19 1 2 | |
20 | |
21 Python dictionary as data:: | |
22 | |
23 1 2 {'weight':7, 'color':'green'} | |
24 | |
25 Arbitrary data:: | |
26 | |
27 1 2 7 green | |
28 """ | |
29 | |
30 __all__ = [ | |
31 "generate_edgelist", | |
32 "write_edgelist", | |
33 "parse_edgelist", | |
34 "read_edgelist", | |
35 "read_weighted_edgelist", | |
36 "write_weighted_edgelist", | |
37 ] | |
38 | |
39 from networkx.utils import open_file | |
40 import networkx as nx | |
41 | |
42 | |
43 def generate_edgelist(G, delimiter=" ", data=True): | |
44 """Generate a single line of the graph G in edge list format. | |
45 | |
46 Parameters | |
47 ---------- | |
48 G : NetworkX graph | |
49 | |
50 delimiter : string, optional | |
51 Separator for node labels | |
52 | |
53 data : bool or list of keys | |
54 If False generate no edge data. If True use a dictionary | |
55 representation of edge data. If a list of keys use a list of data | |
56 values corresponding to the keys. | |
57 | |
58 Returns | |
59 ------- | |
60 lines : string | |
61 Lines of data in adjlist format. | |
62 | |
63 Examples | |
64 -------- | |
65 >>> G = nx.lollipop_graph(4, 3) | |
66 >>> G[1][2]["weight"] = 3 | |
67 >>> G[3][4]["capacity"] = 12 | |
68 >>> for line in nx.generate_edgelist(G, data=False): | |
69 ... print(line) | |
70 0 1 | |
71 0 2 | |
72 0 3 | |
73 1 2 | |
74 1 3 | |
75 2 3 | |
76 3 4 | |
77 4 5 | |
78 5 6 | |
79 | |
80 >>> for line in nx.generate_edgelist(G): | |
81 ... print(line) | |
82 0 1 {} | |
83 0 2 {} | |
84 0 3 {} | |
85 1 2 {'weight': 3} | |
86 1 3 {} | |
87 2 3 {} | |
88 3 4 {'capacity': 12} | |
89 4 5 {} | |
90 5 6 {} | |
91 | |
92 >>> for line in nx.generate_edgelist(G, data=["weight"]): | |
93 ... print(line) | |
94 0 1 | |
95 0 2 | |
96 0 3 | |
97 1 2 3 | |
98 1 3 | |
99 2 3 | |
100 3 4 | |
101 4 5 | |
102 5 6 | |
103 | |
104 See Also | |
105 -------- | |
106 write_adjlist, read_adjlist | |
107 """ | |
108 if data is True: | |
109 for u, v, d in G.edges(data=True): | |
110 e = u, v, dict(d) | |
111 yield delimiter.join(map(str, e)) | |
112 elif data is False: | |
113 for u, v in G.edges(data=False): | |
114 e = u, v | |
115 yield delimiter.join(map(str, e)) | |
116 else: | |
117 for u, v, d in G.edges(data=True): | |
118 e = [u, v] | |
119 try: | |
120 e.extend(d[k] for k in data) | |
121 except KeyError: | |
122 pass # missing data for this edge, should warn? | |
123 yield delimiter.join(map(str, e)) | |
124 | |
125 | |
126 @open_file(1, mode="wb") | |
127 def write_edgelist(G, path, comments="#", delimiter=" ", data=True, encoding="utf-8"): | |
128 """Write graph as a list of edges. | |
129 | |
130 Parameters | |
131 ---------- | |
132 G : graph | |
133 A NetworkX graph | |
134 path : file or string | |
135 File or filename to write. If a file is provided, it must be | |
136 opened in 'wb' mode. Filenames ending in .gz or .bz2 will be compressed. | |
137 comments : string, optional | |
138 The character used to indicate the start of a comment | |
139 delimiter : string, optional | |
140 The string used to separate values. The default is whitespace. | |
141 data : bool or list, optional | |
142 If False write no edge data. | |
143 If True write a string representation of the edge data dictionary.. | |
144 If a list (or other iterable) is provided, write the keys specified | |
145 in the list. | |
146 encoding: string, optional | |
147 Specify which encoding to use when writing file. | |
148 | |
149 Examples | |
150 -------- | |
151 >>> G = nx.path_graph(4) | |
152 >>> nx.write_edgelist(G, "test.edgelist") | |
153 >>> G = nx.path_graph(4) | |
154 >>> fh = open("test.edgelist", "wb") | |
155 >>> nx.write_edgelist(G, fh) | |
156 >>> nx.write_edgelist(G, "test.edgelist.gz") | |
157 >>> nx.write_edgelist(G, "test.edgelist.gz", data=False) | |
158 | |
159 >>> G = nx.Graph() | |
160 >>> G.add_edge(1, 2, weight=7, color="red") | |
161 >>> nx.write_edgelist(G, "test.edgelist", data=False) | |
162 >>> nx.write_edgelist(G, "test.edgelist", data=["color"]) | |
163 >>> nx.write_edgelist(G, "test.edgelist", data=["color", "weight"]) | |
164 | |
165 See Also | |
166 -------- | |
167 read_edgelist | |
168 write_weighted_edgelist | |
169 """ | |
170 | |
171 for line in generate_edgelist(G, delimiter, data): | |
172 line += "\n" | |
173 path.write(line.encode(encoding)) | |
174 | |
175 | |
176 def parse_edgelist( | |
177 lines, comments="#", delimiter=None, create_using=None, nodetype=None, data=True | |
178 ): | |
179 """Parse lines of an edge list representation of a graph. | |
180 | |
181 Parameters | |
182 ---------- | |
183 lines : list or iterator of strings | |
184 Input data in edgelist format | |
185 comments : string, optional | |
186 Marker for comment lines. Default is `'#'` | |
187 delimiter : string, optional | |
188 Separator for node labels. Default is `None`, meaning any whitespace. | |
189 create_using : NetworkX graph constructor, optional (default=nx.Graph) | |
190 Graph type to create. If graph instance, then cleared before populated. | |
191 nodetype : Python type, optional | |
192 Convert nodes to this type. Default is `None`, meaning no conversion is | |
193 performed. | |
194 data : bool or list of (label,type) tuples | |
195 If `False` generate no edge data or if `True` use a dictionary | |
196 representation of edge data or a list tuples specifying dictionary | |
197 key names and types for edge data. | |
198 | |
199 Returns | |
200 ------- | |
201 G: NetworkX Graph | |
202 The graph corresponding to lines | |
203 | |
204 Examples | |
205 -------- | |
206 Edgelist with no data: | |
207 | |
208 >>> lines = ["1 2", "2 3", "3 4"] | |
209 >>> G = nx.parse_edgelist(lines, nodetype=int) | |
210 >>> list(G) | |
211 [1, 2, 3, 4] | |
212 >>> list(G.edges()) | |
213 [(1, 2), (2, 3), (3, 4)] | |
214 | |
215 Edgelist with data in Python dictionary representation: | |
216 | |
217 >>> lines = ["1 2 {'weight': 3}", "2 3 {'weight': 27}", "3 4 {'weight': 3.0}"] | |
218 >>> G = nx.parse_edgelist(lines, nodetype=int) | |
219 >>> list(G) | |
220 [1, 2, 3, 4] | |
221 >>> list(G.edges(data=True)) | |
222 [(1, 2, {'weight': 3}), (2, 3, {'weight': 27}), (3, 4, {'weight': 3.0})] | |
223 | |
224 Edgelist with data in a list: | |
225 | |
226 >>> lines = ["1 2 3", "2 3 27", "3 4 3.0"] | |
227 >>> G = nx.parse_edgelist(lines, nodetype=int, data=(("weight", float),)) | |
228 >>> list(G) | |
229 [1, 2, 3, 4] | |
230 >>> list(G.edges(data=True)) | |
231 [(1, 2, {'weight': 3.0}), (2, 3, {'weight': 27.0}), (3, 4, {'weight': 3.0})] | |
232 | |
233 See Also | |
234 -------- | |
235 read_weighted_edgelist | |
236 """ | |
237 from ast import literal_eval | |
238 | |
239 G = nx.empty_graph(0, create_using) | |
240 for line in lines: | |
241 p = line.find(comments) | |
242 if p >= 0: | |
243 line = line[:p] | |
244 if not line: | |
245 continue | |
246 # split line, should have 2 or more | |
247 s = line.strip().split(delimiter) | |
248 if len(s) < 2: | |
249 continue | |
250 u = s.pop(0) | |
251 v = s.pop(0) | |
252 d = s | |
253 if nodetype is not None: | |
254 try: | |
255 u = nodetype(u) | |
256 v = nodetype(v) | |
257 except Exception as e: | |
258 raise TypeError( | |
259 f"Failed to convert nodes {u},{v} to type {nodetype}." | |
260 ) from e | |
261 | |
262 if len(d) == 0 or data is False: | |
263 # no data or data type specified | |
264 edgedata = {} | |
265 elif data is True: | |
266 # no edge types specified | |
267 try: # try to evaluate as dictionary | |
268 if delimiter == ",": | |
269 edgedata_str = ",".join(d) | |
270 else: | |
271 edgedata_str = " ".join(d) | |
272 edgedata = dict(literal_eval(edgedata_str.strip())) | |
273 except Exception as e: | |
274 raise TypeError( | |
275 f"Failed to convert edge data ({d}) to dictionary." | |
276 ) from e | |
277 else: | |
278 # convert edge data to dictionary with specified keys and type | |
279 if len(d) != len(data): | |
280 raise IndexError( | |
281 f"Edge data {d} and data_keys {data} are not the same length" | |
282 ) | |
283 edgedata = {} | |
284 for (edge_key, edge_type), edge_value in zip(data, d): | |
285 try: | |
286 edge_value = edge_type(edge_value) | |
287 except Exception as e: | |
288 raise TypeError( | |
289 f"Failed to convert {edge_key} data {edge_value} " | |
290 f"to type {edge_type}." | |
291 ) from e | |
292 edgedata.update({edge_key: edge_value}) | |
293 G.add_edge(u, v, **edgedata) | |
294 return G | |
295 | |
296 | |
297 @open_file(0, mode="rb") | |
298 def read_edgelist( | |
299 path, | |
300 comments="#", | |
301 delimiter=None, | |
302 create_using=None, | |
303 nodetype=None, | |
304 data=True, | |
305 edgetype=None, | |
306 encoding="utf-8", | |
307 ): | |
308 """Read a graph from a list of edges. | |
309 | |
310 Parameters | |
311 ---------- | |
312 path : file or string | |
313 File or filename to read. If a file is provided, it must be | |
314 opened in 'rb' mode. | |
315 Filenames ending in .gz or .bz2 will be uncompressed. | |
316 comments : string, optional | |
317 The character used to indicate the start of a comment. | |
318 delimiter : string, optional | |
319 The string used to separate values. The default is whitespace. | |
320 create_using : NetworkX graph constructor, optional (default=nx.Graph) | |
321 Graph type to create. If graph instance, then cleared before populated. | |
322 nodetype : int, float, str, Python type, optional | |
323 Convert node data from strings to specified type | |
324 data : bool or list of (label,type) tuples | |
325 Tuples specifying dictionary key names and types for edge data | |
326 edgetype : int, float, str, Python type, optional OBSOLETE | |
327 Convert edge data from strings to specified type and use as 'weight' | |
328 encoding: string, optional | |
329 Specify which encoding to use when reading file. | |
330 | |
331 Returns | |
332 ------- | |
333 G : graph | |
334 A networkx Graph or other type specified with create_using | |
335 | |
336 Examples | |
337 -------- | |
338 >>> nx.write_edgelist(nx.path_graph(4), "test.edgelist") | |
339 >>> G = nx.read_edgelist("test.edgelist") | |
340 | |
341 >>> fh = open("test.edgelist", "rb") | |
342 >>> G = nx.read_edgelist(fh) | |
343 >>> fh.close() | |
344 | |
345 >>> G = nx.read_edgelist("test.edgelist", nodetype=int) | |
346 >>> G = nx.read_edgelist("test.edgelist", create_using=nx.DiGraph) | |
347 | |
348 Edgelist with data in a list: | |
349 | |
350 >>> textline = "1 2 3" | |
351 >>> fh = open("test.edgelist", "w") | |
352 >>> d = fh.write(textline) | |
353 >>> fh.close() | |
354 >>> G = nx.read_edgelist("test.edgelist", nodetype=int, data=(("weight", float),)) | |
355 >>> list(G) | |
356 [1, 2] | |
357 >>> list(G.edges(data=True)) | |
358 [(1, 2, {'weight': 3.0})] | |
359 | |
360 See parse_edgelist() for more examples of formatting. | |
361 | |
362 See Also | |
363 -------- | |
364 parse_edgelist | |
365 write_edgelist | |
366 | |
367 Notes | |
368 ----- | |
369 Since nodes must be hashable, the function nodetype must return hashable | |
370 types (e.g. int, float, str, frozenset - or tuples of those, etc.) | |
371 """ | |
372 lines = (line if isinstance(line, str) else line.decode(encoding) for line in path) | |
373 return parse_edgelist( | |
374 lines, | |
375 comments=comments, | |
376 delimiter=delimiter, | |
377 create_using=create_using, | |
378 nodetype=nodetype, | |
379 data=data, | |
380 ) | |
381 | |
382 | |
383 def write_weighted_edgelist(G, path, comments="#", delimiter=" ", encoding="utf-8"): | |
384 """Write graph G as a list of edges with numeric weights. | |
385 | |
386 Parameters | |
387 ---------- | |
388 G : graph | |
389 A NetworkX graph | |
390 path : file or string | |
391 File or filename to write. If a file is provided, it must be | |
392 opened in 'wb' mode. | |
393 Filenames ending in .gz or .bz2 will be compressed. | |
394 comments : string, optional | |
395 The character used to indicate the start of a comment | |
396 delimiter : string, optional | |
397 The string used to separate values. The default is whitespace. | |
398 encoding: string, optional | |
399 Specify which encoding to use when writing file. | |
400 | |
401 Examples | |
402 -------- | |
403 >>> G = nx.Graph() | |
404 >>> G.add_edge(1, 2, weight=7) | |
405 >>> nx.write_weighted_edgelist(G, "test.weighted.edgelist") | |
406 | |
407 See Also | |
408 -------- | |
409 read_edgelist | |
410 write_edgelist | |
411 read_weighted_edgelist | |
412 """ | |
413 write_edgelist( | |
414 G, | |
415 path, | |
416 comments=comments, | |
417 delimiter=delimiter, | |
418 data=("weight",), | |
419 encoding=encoding, | |
420 ) | |
421 | |
422 | |
423 def read_weighted_edgelist( | |
424 path, | |
425 comments="#", | |
426 delimiter=None, | |
427 create_using=None, | |
428 nodetype=None, | |
429 encoding="utf-8", | |
430 ): | |
431 """Read a graph as list of edges with numeric weights. | |
432 | |
433 Parameters | |
434 ---------- | |
435 path : file or string | |
436 File or filename to read. If a file is provided, it must be | |
437 opened in 'rb' mode. | |
438 Filenames ending in .gz or .bz2 will be uncompressed. | |
439 comments : string, optional | |
440 The character used to indicate the start of a comment. | |
441 delimiter : string, optional | |
442 The string used to separate values. The default is whitespace. | |
443 create_using : NetworkX graph constructor, optional (default=nx.Graph) | |
444 Graph type to create. If graph instance, then cleared before populated. | |
445 nodetype : int, float, str, Python type, optional | |
446 Convert node data from strings to specified type | |
447 encoding: string, optional | |
448 Specify which encoding to use when reading file. | |
449 | |
450 Returns | |
451 ------- | |
452 G : graph | |
453 A networkx Graph or other type specified with create_using | |
454 | |
455 Notes | |
456 ----- | |
457 Since nodes must be hashable, the function nodetype must return hashable | |
458 types (e.g. int, float, str, frozenset - or tuples of those, etc.) | |
459 | |
460 Example edgelist file format. | |
461 | |
462 With numeric edge data:: | |
463 | |
464 # read with | |
465 # >>> G=nx.read_weighted_edgelist(fh) | |
466 # source target data | |
467 a b 1 | |
468 a c 3.14159 | |
469 d e 42 | |
470 | |
471 See Also | |
472 -------- | |
473 write_weighted_edgelist | |
474 """ | |
475 return read_edgelist( | |
476 path, | |
477 comments=comments, | |
478 delimiter=delimiter, | |
479 create_using=create_using, | |
480 nodetype=nodetype, | |
481 data=(("weight", float),), | |
482 encoding=encoding, | |
483 ) |