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 ) |
