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 )