comparison env/lib/python3.7/site-packages/networkx/convert.py @ 5:9b1c78e6ba9c draft default tip

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