Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/networkx/convert.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 """Functions to convert NetworkX graphs to and from other formats. | |
| 2 | |
| 3 The preferred way of converting data to a NetworkX graph is through the | |
| 4 graph constructor. The constructor calls the to_networkx_graph() function | |
| 5 which attempts to guess the input type and convert it automatically. | |
| 6 | |
| 7 Examples | |
| 8 -------- | |
| 9 Create a graph with a single edge from a dictionary of dictionaries | |
| 10 | |
| 11 >>> d = {0: {1: 1}} # dict-of-dicts single edge (0,1) | |
| 12 >>> G = nx.Graph(d) | |
| 13 | |
| 14 See Also | |
| 15 -------- | |
| 16 nx_agraph, nx_pydot | |
| 17 """ | |
| 18 import warnings | |
| 19 import networkx as nx | |
| 20 from collections.abc import Collection, Generator, Iterator | |
| 21 | |
| 22 __all__ = [ | |
| 23 "to_networkx_graph", | |
| 24 "from_dict_of_dicts", | |
| 25 "to_dict_of_dicts", | |
| 26 "from_dict_of_lists", | |
| 27 "to_dict_of_lists", | |
| 28 "from_edgelist", | |
| 29 "to_edgelist", | |
| 30 ] | |
| 31 | |
| 32 | |
| 33 def to_networkx_graph(data, create_using=None, multigraph_input=False): | |
| 34 """Make a NetworkX graph from a known data structure. | |
| 35 | |
| 36 The preferred way to call this is automatically | |
| 37 from the class constructor | |
| 38 | |
| 39 >>> d = {0: {1: {"weight": 1}}} # dict-of-dicts single edge (0,1) | |
| 40 >>> G = nx.Graph(d) | |
| 41 | |
| 42 instead of the equivalent | |
| 43 | |
| 44 >>> G = nx.from_dict_of_dicts(d) | |
| 45 | |
| 46 Parameters | |
| 47 ---------- | |
| 48 data : object to be converted | |
| 49 | |
| 50 Current known types are: | |
| 51 any NetworkX graph | |
| 52 dict-of-dicts | |
| 53 dict-of-lists | |
| 54 container (e.g. set, list, tuple) of edges | |
| 55 iterator (e.g. itertools.chain) that produces edges | |
| 56 generator of edges | |
| 57 Pandas DataFrame (row per edge) | |
| 58 numpy matrix | |
| 59 numpy ndarray | |
| 60 scipy sparse matrix | |
| 61 pygraphviz agraph | |
| 62 | |
| 63 create_using : NetworkX graph constructor, optional (default=nx.Graph) | |
| 64 Graph type to create. If graph instance, then cleared before populated. | |
| 65 | |
| 66 multigraph_input : bool (default False) | |
| 67 If True and data is a dict_of_dicts, | |
| 68 try to create a multigraph assuming dict_of_dict_of_lists. | |
| 69 If data and create_using are both multigraphs then create | |
| 70 a multigraph from a multigraph. | |
| 71 | |
| 72 """ | |
| 73 # NX graph | |
| 74 if hasattr(data, "adj"): | |
| 75 try: | |
| 76 result = from_dict_of_dicts( | |
| 77 data.adj, | |
| 78 create_using=create_using, | |
| 79 multigraph_input=data.is_multigraph(), | |
| 80 ) | |
| 81 if hasattr(data, "graph"): # data.graph should be dict-like | |
| 82 result.graph.update(data.graph) | |
| 83 if hasattr(data, "nodes"): # data.nodes should be dict-like | |
| 84 # result.add_node_from(data.nodes.items()) possible but | |
| 85 # for custom node_attr_dict_factory which may be hashable | |
| 86 # will be unexpected behavior | |
| 87 for n, dd in data.nodes.items(): | |
| 88 result._node[n].update(dd) | |
| 89 return result | |
| 90 except Exception as e: | |
| 91 raise nx.NetworkXError("Input is not a correct NetworkX graph.") from e | |
| 92 | |
| 93 # pygraphviz agraph | |
| 94 if hasattr(data, "is_strict"): | |
| 95 try: | |
| 96 return nx.nx_agraph.from_agraph(data, create_using=create_using) | |
| 97 except Exception as e: | |
| 98 raise nx.NetworkXError("Input is not a correct pygraphviz graph.") from e | |
| 99 | |
| 100 # dict of dicts/lists | |
| 101 if isinstance(data, dict): | |
| 102 try: | |
| 103 return from_dict_of_dicts( | |
| 104 data, create_using=create_using, multigraph_input=multigraph_input | |
| 105 ) | |
| 106 except: | |
| 107 try: | |
| 108 return from_dict_of_lists(data, create_using=create_using) | |
| 109 except Exception as e: | |
| 110 raise TypeError("Input is not known type.") from e | |
| 111 | |
| 112 # Pandas DataFrame | |
| 113 try: | |
| 114 import pandas as pd | |
| 115 | |
| 116 if isinstance(data, pd.DataFrame): | |
| 117 if data.shape[0] == data.shape[1]: | |
| 118 try: | |
| 119 return nx.from_pandas_adjacency(data, create_using=create_using) | |
| 120 except Exception as e: | |
| 121 msg = "Input is not a correct Pandas DataFrame adjacency matrix." | |
| 122 raise nx.NetworkXError(msg) from e | |
| 123 else: | |
| 124 try: | |
| 125 return nx.from_pandas_edgelist( | |
| 126 data, edge_attr=True, create_using=create_using | |
| 127 ) | |
| 128 except Exception as e: | |
| 129 msg = "Input is not a correct Pandas DataFrame edge-list." | |
| 130 raise nx.NetworkXError(msg) from e | |
| 131 except ImportError: | |
| 132 msg = "pandas not found, skipping conversion test." | |
| 133 warnings.warn(msg, ImportWarning) | |
| 134 | |
| 135 # numpy matrix or ndarray | |
| 136 try: | |
| 137 import numpy | |
| 138 | |
| 139 if isinstance(data, (numpy.matrix, numpy.ndarray)): | |
| 140 try: | |
| 141 return nx.from_numpy_matrix(data, create_using=create_using) | |
| 142 except Exception as e: | |
| 143 raise nx.NetworkXError( | |
| 144 "Input is not a correct numpy matrix or array." | |
| 145 ) from e | |
| 146 except ImportError: | |
| 147 warnings.warn("numpy not found, skipping conversion test.", ImportWarning) | |
| 148 | |
| 149 # scipy sparse matrix - any format | |
| 150 try: | |
| 151 import scipy | |
| 152 | |
| 153 if hasattr(data, "format"): | |
| 154 try: | |
| 155 return nx.from_scipy_sparse_matrix(data, create_using=create_using) | |
| 156 except Exception as e: | |
| 157 raise nx.NetworkXError( | |
| 158 "Input is not a correct scipy sparse matrix type." | |
| 159 ) from e | |
| 160 except ImportError: | |
| 161 warnings.warn("scipy not found, skipping conversion test.", ImportWarning) | |
| 162 | |
| 163 # Note: most general check - should remain last in order of execution | |
| 164 # Includes containers (e.g. list, set, dict, etc.), generators, and | |
| 165 # iterators (e.g. itertools.chain) of edges | |
| 166 | |
| 167 if isinstance(data, (Collection, Generator, Iterator)): | |
| 168 try: | |
| 169 return from_edgelist(data, create_using=create_using) | |
| 170 except Exception as e: | |
| 171 raise nx.NetworkXError("Input is not a valid edge list") from e | |
| 172 | |
| 173 raise nx.NetworkXError("Input is not a known data type for conversion.") | |
| 174 | |
| 175 | |
| 176 def to_dict_of_lists(G, nodelist=None): | |
| 177 """Returns adjacency representation of graph as a dictionary of lists. | |
| 178 | |
| 179 Parameters | |
| 180 ---------- | |
| 181 G : graph | |
| 182 A NetworkX graph | |
| 183 | |
| 184 nodelist : list | |
| 185 Use only nodes specified in nodelist | |
| 186 | |
| 187 Notes | |
| 188 ----- | |
| 189 Completely ignores edge data for MultiGraph and MultiDiGraph. | |
| 190 | |
| 191 """ | |
| 192 if nodelist is None: | |
| 193 nodelist = G | |
| 194 | |
| 195 d = {} | |
| 196 for n in nodelist: | |
| 197 d[n] = [nbr for nbr in G.neighbors(n) if nbr in nodelist] | |
| 198 return d | |
| 199 | |
| 200 | |
| 201 def from_dict_of_lists(d, create_using=None): | |
| 202 """Returns a graph from a dictionary of lists. | |
| 203 | |
| 204 Parameters | |
| 205 ---------- | |
| 206 d : dictionary of lists | |
| 207 A dictionary of lists adjacency representation. | |
| 208 | |
| 209 create_using : NetworkX graph constructor, optional (default=nx.Graph) | |
| 210 Graph type to create. If graph instance, then cleared before populated. | |
| 211 | |
| 212 Examples | |
| 213 -------- | |
| 214 >>> dol = {0: [1]} # single edge (0,1) | |
| 215 >>> G = nx.from_dict_of_lists(dol) | |
| 216 | |
| 217 or | |
| 218 | |
| 219 >>> G = nx.Graph(dol) # use Graph constructor | |
| 220 | |
| 221 """ | |
| 222 G = nx.empty_graph(0, create_using) | |
| 223 G.add_nodes_from(d) | |
| 224 if G.is_multigraph() and not G.is_directed(): | |
| 225 # a dict_of_lists can't show multiedges. BUT for undirected graphs, | |
| 226 # each edge shows up twice in the dict_of_lists. | |
| 227 # So we need to treat this case separately. | |
| 228 seen = {} | |
| 229 for node, nbrlist in d.items(): | |
| 230 for nbr in nbrlist: | |
| 231 if nbr not in seen: | |
| 232 G.add_edge(node, nbr) | |
| 233 seen[node] = 1 # don't allow reverse edge to show up | |
| 234 else: | |
| 235 G.add_edges_from( | |
| 236 ((node, nbr) for node, nbrlist in d.items() for nbr in nbrlist) | |
| 237 ) | |
| 238 return G | |
| 239 | |
| 240 | |
| 241 def to_dict_of_dicts(G, nodelist=None, edge_data=None): | |
| 242 """Returns adjacency representation of graph as a dictionary of dictionaries. | |
| 243 | |
| 244 Parameters | |
| 245 ---------- | |
| 246 G : graph | |
| 247 A NetworkX graph | |
| 248 | |
| 249 nodelist : list | |
| 250 Use only nodes specified in nodelist | |
| 251 | |
| 252 edge_data : list, optional | |
| 253 If provided, the value of the dictionary will be | |
| 254 set to edge_data for all edges. This is useful to make | |
| 255 an adjacency matrix type representation with 1 as the edge data. | |
| 256 If edgedata is None, the edgedata in G is used to fill the values. | |
| 257 If G is a multigraph, the edgedata is a dict for each pair (u,v). | |
| 258 """ | |
| 259 dod = {} | |
| 260 if nodelist is None: | |
| 261 if edge_data is None: | |
| 262 for u, nbrdict in G.adjacency(): | |
| 263 dod[u] = nbrdict.copy() | |
| 264 else: # edge_data is not None | |
| 265 for u, nbrdict in G.adjacency(): | |
| 266 dod[u] = dod.fromkeys(nbrdict, edge_data) | |
| 267 else: # nodelist is not None | |
| 268 if edge_data is None: | |
| 269 for u in nodelist: | |
| 270 dod[u] = {} | |
| 271 for v, data in ((v, data) for v, data in G[u].items() if v in nodelist): | |
| 272 dod[u][v] = data | |
| 273 else: # nodelist and edge_data are not None | |
| 274 for u in nodelist: | |
| 275 dod[u] = {} | |
| 276 for v in (v for v in G[u] if v in nodelist): | |
| 277 dod[u][v] = edge_data | |
| 278 return dod | |
| 279 | |
| 280 | |
| 281 def from_dict_of_dicts(d, create_using=None, multigraph_input=False): | |
| 282 """Returns a graph from a dictionary of dictionaries. | |
| 283 | |
| 284 Parameters | |
| 285 ---------- | |
| 286 d : dictionary of dictionaries | |
| 287 A dictionary of dictionaries adjacency representation. | |
| 288 | |
| 289 create_using : NetworkX graph constructor, optional (default=nx.Graph) | |
| 290 Graph type to create. If graph instance, then cleared before populated. | |
| 291 | |
| 292 multigraph_input : bool (default False) | |
| 293 When True, the values of the inner dict are assumed | |
| 294 to be containers of edge data for multiple edges. | |
| 295 Otherwise this routine assumes the edge data are singletons. | |
| 296 | |
| 297 Examples | |
| 298 -------- | |
| 299 >>> dod = {0: {1: {"weight": 1}}} # single edge (0,1) | |
| 300 >>> G = nx.from_dict_of_dicts(dod) | |
| 301 | |
| 302 or | |
| 303 | |
| 304 >>> G = nx.Graph(dod) # use Graph constructor | |
| 305 | |
| 306 """ | |
| 307 G = nx.empty_graph(0, create_using) | |
| 308 G.add_nodes_from(d) | |
| 309 # is dict a MultiGraph or MultiDiGraph? | |
| 310 if multigraph_input: | |
| 311 # make a copy of the list of edge data (but not the edge data) | |
| 312 if G.is_directed(): | |
| 313 if G.is_multigraph(): | |
| 314 G.add_edges_from( | |
| 315 (u, v, key, data) | |
| 316 for u, nbrs in d.items() | |
| 317 for v, datadict in nbrs.items() | |
| 318 for key, data in datadict.items() | |
| 319 ) | |
| 320 else: | |
| 321 G.add_edges_from( | |
| 322 (u, v, data) | |
| 323 for u, nbrs in d.items() | |
| 324 for v, datadict in nbrs.items() | |
| 325 for key, data in datadict.items() | |
| 326 ) | |
| 327 else: # Undirected | |
| 328 if G.is_multigraph(): | |
| 329 seen = set() # don't add both directions of undirected graph | |
| 330 for u, nbrs in d.items(): | |
| 331 for v, datadict in nbrs.items(): | |
| 332 if (u, v) not in seen: | |
| 333 G.add_edges_from( | |
| 334 (u, v, key, data) for key, data in datadict.items() | |
| 335 ) | |
| 336 seen.add((v, u)) | |
| 337 else: | |
| 338 seen = set() # don't add both directions of undirected graph | |
| 339 for u, nbrs in d.items(): | |
| 340 for v, datadict in nbrs.items(): | |
| 341 if (u, v) not in seen: | |
| 342 G.add_edges_from( | |
| 343 (u, v, data) for key, data in datadict.items() | |
| 344 ) | |
| 345 seen.add((v, u)) | |
| 346 | |
| 347 else: # not a multigraph to multigraph transfer | |
| 348 if G.is_multigraph() and not G.is_directed(): | |
| 349 # d can have both representations u-v, v-u in dict. Only add one. | |
| 350 # We don't need this check for digraphs since we add both directions, | |
| 351 # or for Graph() since it is done implicitly (parallel edges not allowed) | |
| 352 seen = set() | |
| 353 for u, nbrs in d.items(): | |
| 354 for v, data in nbrs.items(): | |
| 355 if (u, v) not in seen: | |
| 356 G.add_edge(u, v, key=0) | |
| 357 G[u][v][0].update(data) | |
| 358 seen.add((v, u)) | |
| 359 else: | |
| 360 G.add_edges_from( | |
| 361 ((u, v, data) for u, nbrs in d.items() for v, data in nbrs.items()) | |
| 362 ) | |
| 363 return G | |
| 364 | |
| 365 | |
| 366 def to_edgelist(G, nodelist=None): | |
| 367 """Returns a list of edges in the graph. | |
| 368 | |
| 369 Parameters | |
| 370 ---------- | |
| 371 G : graph | |
| 372 A NetworkX graph | |
| 373 | |
| 374 nodelist : list | |
| 375 Use only nodes specified in nodelist | |
| 376 | |
| 377 """ | |
| 378 if nodelist is None: | |
| 379 return G.edges(data=True) | |
| 380 return G.edges(nodelist, data=True) | |
| 381 | |
| 382 | |
| 383 def from_edgelist(edgelist, create_using=None): | |
| 384 """Returns a graph from a list of edges. | |
| 385 | |
| 386 Parameters | |
| 387 ---------- | |
| 388 edgelist : list or iterator | |
| 389 Edge tuples | |
| 390 | |
| 391 create_using : NetworkX graph constructor, optional (default=nx.Graph) | |
| 392 Graph type to create. If graph instance, then cleared before populated. | |
| 393 | |
| 394 Examples | |
| 395 -------- | |
| 396 >>> edgelist = [(0, 1)] # single edge (0,1) | |
| 397 >>> G = nx.from_edgelist(edgelist) | |
| 398 | |
| 399 or | |
| 400 | |
| 401 >>> G = nx.Graph(edgelist) # use Graph constructor | |
| 402 | |
| 403 """ | |
| 404 G = nx.empty_graph(0, create_using) | |
| 405 G.add_edges_from(edgelist) | |
| 406 return G |
