Mercurial > repos > shellac > sam_consensus_v3
comparison env/lib/python3.9/site-packages/networkx/algorithms/bipartite/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 Bipartite Edge Lists | |
4 ******************** | |
5 Read and write NetworkX graphs as bipartite edge lists. | |
6 | |
7 Format | |
8 ------ | |
9 You can read or write three formats of edge lists with these functions. | |
10 | |
11 Node pairs with no data:: | |
12 | |
13 1 2 | |
14 | |
15 Python dictionary as data:: | |
16 | |
17 1 2 {'weight':7, 'color':'green'} | |
18 | |
19 Arbitrary data:: | |
20 | |
21 1 2 7 green | |
22 | |
23 For each edge (u, v) the node u is assigned to part 0 and the node v to part 1. | |
24 """ | |
25 __all__ = ["generate_edgelist", "write_edgelist", "parse_edgelist", "read_edgelist"] | |
26 | |
27 import networkx as nx | |
28 from networkx.utils import open_file, not_implemented_for | |
29 | |
30 | |
31 @open_file(1, mode="wb") | |
32 def write_edgelist(G, path, comments="#", delimiter=" ", data=True, encoding="utf-8"): | |
33 """Write a bipartite graph as a list of edges. | |
34 | |
35 Parameters | |
36 ---------- | |
37 G : Graph | |
38 A NetworkX bipartite graph | |
39 path : file or string | |
40 File or filename to write. If a file is provided, it must be | |
41 opened in 'wb' mode. Filenames ending in .gz or .bz2 will be compressed. | |
42 comments : string, optional | |
43 The character used to indicate the start of a comment | |
44 delimiter : string, optional | |
45 The string used to separate values. The default is whitespace. | |
46 data : bool or list, optional | |
47 If False write no edge data. | |
48 If True write a string representation of the edge data dictionary.. | |
49 If a list (or other iterable) is provided, write the keys specified | |
50 in the list. | |
51 encoding: string, optional | |
52 Specify which encoding to use when writing file. | |
53 | |
54 Examples | |
55 -------- | |
56 >>> G = nx.path_graph(4) | |
57 >>> G.add_nodes_from([0, 2], bipartite=0) | |
58 >>> G.add_nodes_from([1, 3], bipartite=1) | |
59 >>> nx.write_edgelist(G, "test.edgelist") | |
60 >>> fh = open("test.edgelist", "wb") | |
61 >>> nx.write_edgelist(G, fh) | |
62 >>> nx.write_edgelist(G, "test.edgelist.gz") | |
63 >>> nx.write_edgelist(G, "test.edgelist.gz", data=False) | |
64 | |
65 >>> G = nx.Graph() | |
66 >>> G.add_edge(1, 2, weight=7, color="red") | |
67 >>> nx.write_edgelist(G, "test.edgelist", data=False) | |
68 >>> nx.write_edgelist(G, "test.edgelist", data=["color"]) | |
69 >>> nx.write_edgelist(G, "test.edgelist", data=["color", "weight"]) | |
70 | |
71 See Also | |
72 -------- | |
73 write_edgelist() | |
74 generate_edgelist() | |
75 """ | |
76 for line in generate_edgelist(G, delimiter, data): | |
77 line += "\n" | |
78 path.write(line.encode(encoding)) | |
79 | |
80 | |
81 @not_implemented_for("directed") | |
82 def generate_edgelist(G, delimiter=" ", data=True): | |
83 """Generate a single line of the bipartite graph G in edge list format. | |
84 | |
85 Parameters | |
86 ---------- | |
87 G : NetworkX graph | |
88 The graph is assumed to have node attribute `part` set to 0,1 representing | |
89 the two graph parts | |
90 | |
91 delimiter : string, optional | |
92 Separator for node labels | |
93 | |
94 data : bool or list of keys | |
95 If False generate no edge data. If True use a dictionary | |
96 representation of edge data. If a list of keys use a list of data | |
97 values corresponding to the keys. | |
98 | |
99 Returns | |
100 ------- | |
101 lines : string | |
102 Lines of data in adjlist format. | |
103 | |
104 Examples | |
105 -------- | |
106 >>> from networkx.algorithms import bipartite | |
107 >>> G = nx.path_graph(4) | |
108 >>> G.add_nodes_from([0, 2], bipartite=0) | |
109 >>> G.add_nodes_from([1, 3], bipartite=1) | |
110 >>> G[1][2]["weight"] = 3 | |
111 >>> G[2][3]["capacity"] = 12 | |
112 >>> for line in bipartite.generate_edgelist(G, data=False): | |
113 ... print(line) | |
114 0 1 | |
115 2 1 | |
116 2 3 | |
117 | |
118 >>> for line in bipartite.generate_edgelist(G): | |
119 ... print(line) | |
120 0 1 {} | |
121 2 1 {'weight': 3} | |
122 2 3 {'capacity': 12} | |
123 | |
124 >>> for line in bipartite.generate_edgelist(G, data=["weight"]): | |
125 ... print(line) | |
126 0 1 | |
127 2 1 3 | |
128 2 3 | |
129 """ | |
130 try: | |
131 part0 = [n for n, d in G.nodes.items() if d["bipartite"] == 0] | |
132 except BaseException as e: | |
133 raise AttributeError("Missing node attribute `bipartite`") from e | |
134 if data is True or data is False: | |
135 for n in part0: | |
136 for e in G.edges(n, data=data): | |
137 yield delimiter.join(map(str, e)) | |
138 else: | |
139 for n in part0: | |
140 for u, v, d in G.edges(n, data=True): | |
141 e = [u, v] | |
142 try: | |
143 e.extend(d[k] for k in data) | |
144 except KeyError: | |
145 pass # missing data for this edge, should warn? | |
146 yield delimiter.join(map(str, e)) | |
147 | |
148 | |
149 def parse_edgelist( | |
150 lines, comments="#", delimiter=None, create_using=None, nodetype=None, data=True | |
151 ): | |
152 """Parse lines of an edge list representation of a bipartite graph. | |
153 | |
154 Parameters | |
155 ---------- | |
156 lines : list or iterator of strings | |
157 Input data in edgelist format | |
158 comments : string, optional | |
159 Marker for comment lines | |
160 delimiter : string, optional | |
161 Separator for node labels | |
162 create_using: NetworkX graph container, optional | |
163 Use given NetworkX graph for holding nodes or edges. | |
164 nodetype : Python type, optional | |
165 Convert nodes to this type. | |
166 data : bool or list of (label,type) tuples | |
167 If False generate no edge data or if True use a dictionary | |
168 representation of edge data or a list tuples specifying dictionary | |
169 key names and types for edge data. | |
170 | |
171 Returns | |
172 ------- | |
173 G: NetworkX Graph | |
174 The bipartite graph corresponding to lines | |
175 | |
176 Examples | |
177 -------- | |
178 Edgelist with no data: | |
179 | |
180 >>> from networkx.algorithms import bipartite | |
181 >>> lines = ["1 2", "2 3", "3 4"] | |
182 >>> G = bipartite.parse_edgelist(lines, nodetype=int) | |
183 >>> sorted(G.nodes()) | |
184 [1, 2, 3, 4] | |
185 >>> sorted(G.nodes(data=True)) | |
186 [(1, {'bipartite': 0}), (2, {'bipartite': 0}), (3, {'bipartite': 0}), (4, {'bipartite': 1})] | |
187 >>> sorted(G.edges()) | |
188 [(1, 2), (2, 3), (3, 4)] | |
189 | |
190 Edgelist with data in Python dictionary representation: | |
191 | |
192 >>> lines = ["1 2 {'weight':3}", "2 3 {'weight':27}", "3 4 {'weight':3.0}"] | |
193 >>> G = bipartite.parse_edgelist(lines, nodetype=int) | |
194 >>> sorted(G.nodes()) | |
195 [1, 2, 3, 4] | |
196 >>> sorted(G.edges(data=True)) | |
197 [(1, 2, {'weight': 3}), (2, 3, {'weight': 27}), (3, 4, {'weight': 3.0})] | |
198 | |
199 Edgelist with data in a list: | |
200 | |
201 >>> lines = ["1 2 3", "2 3 27", "3 4 3.0"] | |
202 >>> G = bipartite.parse_edgelist(lines, nodetype=int, data=(("weight", float),)) | |
203 >>> sorted(G.nodes()) | |
204 [1, 2, 3, 4] | |
205 >>> sorted(G.edges(data=True)) | |
206 [(1, 2, {'weight': 3.0}), (2, 3, {'weight': 27.0}), (3, 4, {'weight': 3.0})] | |
207 | |
208 See Also | |
209 -------- | |
210 """ | |
211 from ast import literal_eval | |
212 | |
213 G = nx.empty_graph(0, create_using) | |
214 for line in lines: | |
215 p = line.find(comments) | |
216 if p >= 0: | |
217 line = line[:p] | |
218 if not len(line): | |
219 continue | |
220 # split line, should have 2 or more | |
221 s = line.strip().split(delimiter) | |
222 if len(s) < 2: | |
223 continue | |
224 u = s.pop(0) | |
225 v = s.pop(0) | |
226 d = s | |
227 if nodetype is not None: | |
228 try: | |
229 u = nodetype(u) | |
230 v = nodetype(v) | |
231 except BaseException as e: | |
232 raise TypeError( | |
233 f"Failed to convert nodes {u},{v} " f"to type {nodetype}." | |
234 ) from e | |
235 | |
236 if len(d) == 0 or data is False: | |
237 # no data or data type specified | |
238 edgedata = {} | |
239 elif data is True: | |
240 # no edge types specified | |
241 try: # try to evaluate as dictionary | |
242 edgedata = dict(literal_eval(" ".join(d))) | |
243 except BaseException as e: | |
244 raise TypeError( | |
245 f"Failed to convert edge data ({d})" f"to dictionary." | |
246 ) from e | |
247 else: | |
248 # convert edge data to dictionary with specified keys and type | |
249 if len(d) != len(data): | |
250 raise IndexError( | |
251 f"Edge data {d} and data_keys {data} are not the same length" | |
252 ) | |
253 edgedata = {} | |
254 for (edge_key, edge_type), edge_value in zip(data, d): | |
255 try: | |
256 edge_value = edge_type(edge_value) | |
257 except BaseException as e: | |
258 raise TypeError( | |
259 f"Failed to convert {edge_key} data " | |
260 f"{edge_value} to type {edge_type}." | |
261 ) from e | |
262 edgedata.update({edge_key: edge_value}) | |
263 G.add_node(u, bipartite=0) | |
264 G.add_node(v, bipartite=1) | |
265 G.add_edge(u, v, **edgedata) | |
266 return G | |
267 | |
268 | |
269 @open_file(0, mode="rb") | |
270 def read_edgelist( | |
271 path, | |
272 comments="#", | |
273 delimiter=None, | |
274 create_using=None, | |
275 nodetype=None, | |
276 data=True, | |
277 edgetype=None, | |
278 encoding="utf-8", | |
279 ): | |
280 """Read a bipartite graph from a list of edges. | |
281 | |
282 Parameters | |
283 ---------- | |
284 path : file or string | |
285 File or filename to read. If a file is provided, it must be | |
286 opened in 'rb' mode. | |
287 Filenames ending in .gz or .bz2 will be uncompressed. | |
288 comments : string, optional | |
289 The character used to indicate the start of a comment. | |
290 delimiter : string, optional | |
291 The string used to separate values. The default is whitespace. | |
292 create_using : Graph container, optional, | |
293 Use specified container to build graph. The default is networkx.Graph, | |
294 an undirected graph. | |
295 nodetype : int, float, str, Python type, optional | |
296 Convert node data from strings to specified type | |
297 data : bool or list of (label,type) tuples | |
298 Tuples specifying dictionary key names and types for edge data | |
299 edgetype : int, float, str, Python type, optional OBSOLETE | |
300 Convert edge data from strings to specified type and use as 'weight' | |
301 encoding: string, optional | |
302 Specify which encoding to use when reading file. | |
303 | |
304 Returns | |
305 ------- | |
306 G : graph | |
307 A networkx Graph or other type specified with create_using | |
308 | |
309 Examples | |
310 -------- | |
311 >>> from networkx.algorithms import bipartite | |
312 >>> G = nx.path_graph(4) | |
313 >>> G.add_nodes_from([0, 2], bipartite=0) | |
314 >>> G.add_nodes_from([1, 3], bipartite=1) | |
315 >>> bipartite.write_edgelist(G, "test.edgelist") | |
316 >>> G = bipartite.read_edgelist("test.edgelist") | |
317 | |
318 >>> fh = open("test.edgelist", "rb") | |
319 >>> G = bipartite.read_edgelist(fh) | |
320 >>> fh.close() | |
321 | |
322 >>> G = bipartite.read_edgelist("test.edgelist", nodetype=int) | |
323 | |
324 Edgelist with data in a list: | |
325 | |
326 >>> textline = "1 2 3" | |
327 >>> fh = open("test.edgelist", "w") | |
328 >>> d = fh.write(textline) | |
329 >>> fh.close() | |
330 >>> G = bipartite.read_edgelist( | |
331 ... "test.edgelist", nodetype=int, data=(("weight", float),) | |
332 ... ) | |
333 >>> list(G) | |
334 [1, 2] | |
335 >>> list(G.edges(data=True)) | |
336 [(1, 2, {'weight': 3.0})] | |
337 | |
338 See parse_edgelist() for more examples of formatting. | |
339 | |
340 See Also | |
341 -------- | |
342 parse_edgelist | |
343 | |
344 Notes | |
345 ----- | |
346 Since nodes must be hashable, the function nodetype must return hashable | |
347 types (e.g. int, float, str, frozenset - or tuples of those, etc.) | |
348 """ | |
349 lines = (line.decode(encoding) for line in path) | |
350 return parse_edgelist( | |
351 lines, | |
352 comments=comments, | |
353 delimiter=delimiter, | |
354 create_using=create_using, | |
355 nodetype=nodetype, | |
356 data=data, | |
357 ) |