1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
|
************************
Version 0.99 API changes
************************
The version networkx-0.99 is the penultimate release before
networkx-1.0. We have bumped the version from 0.37 to 0.99 to
indicate (in our unusual version number scheme) that this is a major
change to NetworkX.
We have made some significant changes, detailed below, to NetworkX
to improve performance, functionality, and clarity.
Version 0.99 requires Python 2.4 or greater.
Please send comments and questions to the networkx-discuss mailing list.
http://groups.google.com/group/networkx-discuss
Changes in base classes
=======================
The most significant changes are in the graph classes.
We have redesigned the Graph() and DiGraph() classes
to optionally allow edge data.
This change allows Graph and DiGraph to naturally represent
weighted graphs and to hold arbitrary information on edges.
- Both Graph and DiGraph take an optional argument weighted=True|False.
When weighted=True the graph is assumed to have numeric edge data
(with default 1). The Graph and DiGraph classes in earlier versions
used the Python None as data (which is still allowed as edge data).
- The Graph and DiGraph classes now allow self loops.
- The XGraph and XDiGraph classes are removed and replaced with
MultiGraph and MultiDiGraph. MultiGraph and MultiDiGraph
optionally allow parallel (multiple) edges between two nodes.
The mapping from old to new classes is as follows::
- Graph -> Graph (self loops allowed now, default edge data is 1)
- DiGraph -> DiGraph (self loops allowed now, default edge data is 1)
- XGraph(multiedges=False) -> Graph
- XGraph(multiedges=True) -> MultiGraph
- XDiGraph(multiedges=False) -> DiGraph
- XDiGraph(multiedges=True) -> MultiDiGraph
Methods changed
---------------
edges()
^^^^^^^
New keyword data=True|False keyword determines whether to return
two-tuples (u,v) (False) or three-tuples (u,v,d) (True)
delete_node()
^^^^^^^^^^^^^
The preferred name is now remove_node().
delete_nodes_from()
^^^^^^^^^^^^^^^^^^^
No longer raises an exception on an attempt to delete a node not in
the graph. The preferred name is now remove_nodes_from().
delete_edge()
^^^^^^^^^^^^^^
Now raises an exception on an attempt to delete an edge not in the graph.
The preferred name is now remove_edge().
delete_edges_from()
^^^^^^^^^^^^^^^^^^^
The preferred name is now remove_edges_from().
add_edge()
^^^^^^^^^^
The add_edge() method no longer accepts an edge tuple (u,v)
directly. The tuple must be unpacked into individual nodes.
>>> import networkx as nx
>>> u='a'
>>> v='b'
>>> e=(u,v)
>>> G=nx.Graph()
Old
>>> # G.add_edge((u,v)) # or G.add_edge(e)
New
>>> G.add_edge(*e) # or G.add_edge(*(u,v))
The * operator unpacks the edge tuple in the argument list.
Add edge now has
a data keyword parameter for setting the default (data=1) edge
data.
>>> # G.add_edge('a','b','foo') # add edge with string "foo" as data
>>> # G.add_edge(1,2,5.0) # add edge with float 5 as data
add_edges_from()
^^^^^^^^^^^^^^^^
Now can take list or iterator of either 2-tuples (u,v),
3-tuples (u,v,data) or a mix of both.
Now has data keyword parameter (default 1) for setting the edge data
for any edge in the edge list that is a 2-tuple.
has_edge()
^^^^^^^^^^
The has_edge() method no longer accepts an edge tuple (u,v)
directly. The tuple must be unpacked into individual nodes.
Old:
>>> # G.has_edge((u,v)) # or has_edge(e)
New:
>>> G.has_edge(*e) # or has_edge(*(u,v))
True
The * operator unpacks the edge tuple in the argument list.
get_edge()
^^^^^^^^^^
Now has the keyword argument "default" to specify
what value to return if no edge is found. If not specified
an exception is raised if no edge is found.
The fastest way to get edge data for edge (u,v) is to use G[u][v]
instead of G.get_edge(u,v)
degree_iter()
^^^^^^^^^^^^^
The degree_iter method now returns an iterator over pairs of (node,
degree). This was the previous behavior of degree_iter(with_labels=true)
Also there is a new keyword weighted=False|True for weighted degree.
subgraph()
^^^^^^^^^^
The argument inplace=False|True has been replaced with copy=True|False.
Subgraph no longer takes create_using keyword. To change the graph
type either make a copy of
the graph first and then change type or change type and make
a subgraph. E.g.
>>> G=nx.path_graph(5)
>>> H=nx.DiGraph(G.subgraph([0,1])) # digraph of copy of induced subgraph
__getitem__()
^^^^^^^^^^^^^
Getting node neighbors from the graph with G[v] now returns
a dictionary.
>>> G=nx.path_graph(5)
>>> # G[0]
# {1: 1}
To get a list of neighbors you can either use the keys of that
dictionary or use
>>> G.neighbors(0)
[1]
This change allows algorithms to use the underlying dict-of-dict
representation through G[v] for substantial performance gains.
Warning: The returned dictionary should not be modified as it may
corrupt the graph data structure. Make a copy G[v].copy() if you
wish to modify the dict.
Methods removed
---------------
info()
^^^^^^
now a function
>>> G=nx.Graph(name='test me')
>>> nx.info(G)
Name: test me
Type: Graph
Number of nodes: 0
Number of edges: 0
node_boundary()
^^^^^^^^^^^^^^^
now a function
edge_boundary()
^^^^^^^^^^^^^^^
now a function
is_directed()
^^^^^^^^^^^^^
use the directed attribute
>>> G=nx.DiGraph()
>>> # G.directed
# True
G.out_edges()
^^^^^^^^^^^^^
use G.edges()
G.in_edges()
^^^^^^^^^^^^
use
>>> G=nx.DiGraph()
>>> R=G.reverse()
>>> R.edges()
[]
or
>>> [(v,u) for (u,v) in G.edges()]
[]
Methods added
-------------
adjacency_list()
^^^^^^^^^^^^^^^^
Returns a list-of-lists adjacency list representation of the graph.
adjacency_iter()
^^^^^^^^^^^^^^^^
Returns an iterator of (node, adjacency_dict[node]) over all
nodes in the graph. Intended for fast access to the internal
data structure for use in internal algorithms.
Other possible incompatibilities with existing code
===================================================
Imports
-------
Some of the code modules were moved into subdirectories.
Import statements such as::
import networkx.centrality
from networkx.centrality import *
may no longer work (including that example).
Use either
>>> import networkx # e.g. centrality functions available as networkx.fcn()
or
>>> from networkx import * # e.g. centrality functions available as fcn()
Self-loops
----------
For Graph and DiGraph self loops are now allowed.
This might affect code or algorithms that add self loops
which were intended to be ignored.
Use the methods
- nodes_with_selfloops()
- selfloop_edges()
- number_of_selfloops()
to discover any self loops.
Copy
----
Copies of NetworkX graphs including using the copy() method
now return complete copies of the graph. This means that all
connection information is copied--subsequent changes in the
copy do not change the old graph. But node keys and edge
data in the original and copy graphs are pointers to the same data.
prepare_nbunch
--------------
Used internally - now called nbunch_iter and returns an iterator.
Converting your old code to Version 0.99
========================================
Mostly you can just run the code and python will raise an exception
for features that changed. Common places for changes are
- Converting XGraph() to either Graph or MultiGraph
- Converting XGraph.edges() to Graph.edges(data=True)
- Switching some rarely used methods to attributes (e.g. directed)
or to functions (e.g. node_boundary)
- If you relied on the old default edge data being None, you will
have to account for it now being 1.
You may also want to look through your code for places which could
improve speed or readability. The iterators are helpful with large
graphs and getting edge data via G[u][v] is quite fast. You may also
want to change G.neighbors(n) to G[n] which returns the dict keyed by
neighbor nodes to the edge data. It is faster for many purposes but
does not work well when you are changing the graph.
|