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
|
#-*- coding: utf-8 -*-
# Copyright (C) 2011 by
# Jordi Torrents <jtorrents@milnou.net>
# Aric Hagberg <hagberg@lanl.gov>
# All rights reserved.
# BSD license.
import networkx as nx
__author__ = """\n""".join(['Jordi Torrents <jtorrents@milnou.net>',
'Aric Hagberg (hagberg@lanl.gov)'])
__all__ = ["average_neighbor_degree"]
def _average_nbr_deg(G, source_degree, target_degree, nodes=None, weight=None):
# average degree of neighbors
avg = {}
for n,deg in source_degree(nodes,weight=weight).items():
# normalize but not by zero degree
if deg == 0:
deg = 1
nbrdeg = target_degree(G[n])
if weight is None:
avg[n] = sum(nbrdeg.values())/float(deg)
else:
avg[n] = sum((G[n][nbr].get(weight,1)*d
for nbr,d in nbrdeg.items()))/float(deg)
return avg
def average_neighbor_degree(G, source='out', target='out',
nodes=None, weight=None):
r"""Returns the average degree of the neighborhood of each node.
The average degree of a node `i` is
.. math::
k_{nn,i} = \frac{1}{|N(i)|} \sum_{j \in N(i)} k_j
where `N(i)` are the neighbors of node `i` and `k_j` is
the degree of node `j` which belongs to `N(i)`. For weighted
graphs, an analogous measure can be defined [1]_,
.. math::
k_{nn,i}^{w} = \frac{1}{s_i} \sum_{j \in N(i)} w_{ij} k_j
where `s_i` is the weighted degree of node `i`, `w_{ij}`
is the weight of the edge that links `i` and `j` and
`N(i)` are the neighbors of node `i`.
Parameters
----------
G : NetworkX graph
source : string ("in"|"out")
Directed graphs only.
Use "in"- or "out"-degree for source node.
target : string ("in"|"out")
Directed graphs only.
Use "in"- or "out"-degree for target node.
nodes : list or iterable, optional
Compute neighbor degree for specified nodes. The default is
all nodes in the graph.
weight : string or None, optional (default=None)
The edge attribute that holds the numerical value used as a weight.
If None, then each edge has weight 1.
Returns
-------
d: dict
A dictionary keyed by node with average neighbors degree value.
Examples
--------
>>> G=nx.path_graph(4)
>>> G.edge[0][1]['weight'] = 5
>>> G.edge[2][3]['weight'] = 3
>>> nx.average_neighbor_degree(G)
{0: 2.0, 1: 1.5, 2: 1.5, 3: 2.0}
>>> nx.average_neighbor_degree(G, weight='weight')
{0: 2.0, 1: 1.1666666666666667, 2: 1.25, 3: 2.0}
>>> G=nx.DiGraph()
>>> G.add_path([0,1,2,3])
>>> nx.average_neighbor_degree(G, source='in', target='in')
{0: 1.0, 1: 1.0, 2: 1.0, 3: 0.0}
>>> nx.average_neighbor_degree(G, source='out', target='out')
{0: 1.0, 1: 1.0, 2: 0.0, 3: 0.0}
Notes
-----
For directed graphs you can also specify in-degree or out-degree
by passing keyword arguments.
See Also
--------
average_degree_connectivity
References
----------
.. [1] A. Barrat, M. Barthélemy, R. Pastor-Satorras, and A. Vespignani,
"The architecture of complex weighted networks".
PNAS 101 (11): 3747–3752 (2004).
"""
source_degree = G.degree
target_degree = G.degree
if G.is_directed():
direction = {'out':G.out_degree,
'in':G.in_degree}
source_degree = direction[source]
target_degree = direction[target]
return _average_nbr_deg(G, source_degree, target_degree,
nodes=nodes, weight=weight)
# obsolete
# def average_neighbor_in_degree(G, nodes=None, weight=None):
# if not G.is_directed():
# raise nx.NetworkXError("Not defined for undirected graphs.")
# return _average_nbr_deg(G, G.in_degree, G.in_degree, nodes, weight)
# average_neighbor_in_degree.__doc__=average_neighbor_degree.__doc__
# def average_neighbor_out_degree(G, nodes=None, weight=None):
# if not G.is_directed():
# raise nx.NetworkXError("Not defined for undirected graphs.")
# return _average_nbr_deg(G, G.out_degree, G.out_degree, nodes, weight)
# average_neighbor_out_degree.__doc__=average_neighbor_degree.__doc__
|