summaryrefslogtreecommitdiff
path: root/networkx/algorithms/assortativity/pairs.py
blob: 8516fa4a55031b706286a90215bdda00ab48f5a9 (plain)
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
#-*- coding: utf-8 -*-
"""Generators of  x-y pairs of node data."""
import networkx as nx
from networkx.utils import dict_to_numpy_array
__author__ = ' '.join(['Aric Hagberg <aric.hagberg@gmail.com>'])
__all__ = ['node_attribute_xy',
           'node_degree_xy']

def node_attribute_xy(G, attribute, nodes=None):
    """Return iterator of node-attribute pairs for all edges in G.

    Parameters
    ----------
    G: NetworkX graph

    attribute: key
       The node attribute key.

    nodes: list or iterable (optional)
        Use only edges that are adjacency to specified nodes.
        The default is all nodes.

    Returns
    -------
    (x,y): 2-tuple
        Generates 2-tuple of (attribute,attribute) values.

    Examples
    --------
    >>> G = nx.DiGraph()
    >>> G.add_node(1,color='red')
    >>> G.add_node(2,color='blue')
    >>> G.add_edge(1,2)
    >>> list(nx.node_attribute_xy(G,'color'))
    [('red', 'blue')]

    Notes
    -----
    For undirected graphs each edge is produced twice, once for each edge 
    representation (u,v) and (v,u), with the exception of self-loop edges 
    which only appear once.
    """
    if nodes is None:
        nodes = set(G)
    else:
        nodes = set(nodes)
    node = G.node 
    for u,nbrsdict in G.adjacency_iter():
        if u not in nodes:
            continue
        uattr = node[u].get(attribute,None)
        if G.is_multigraph():
            for v,keys in nbrsdict.items():
                vattr = node[v].get(attribute,None)                
                for k,d in keys.items():
                    yield (uattr,vattr)
        else:
            for v,eattr in nbrsdict.items():
                vattr = node[v].get(attribute,None)
                yield (uattr,vattr)


def node_degree_xy(G, x='out', y='in', weight=None, nodes=None):
    """Generate node degree-degree pairs for edges in G.

    Parameters
    ----------
    G: NetworkX graph

    x: string ('in','out')
       The degree type for source node (directed graphs only).

    y: string ('in','out')
       The degree type for target node (directed graphs only).

    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.
       The degree is the sum of the edge weights adjacent to the node.

    nodes: list or iterable (optional)
        Use only edges that are adjacency to specified nodes.
        The default is all nodes.

    Returns
    -------
    (x,y): 2-tuple
        Generates 2-tuple of (degree,degree) values.


    Examples
    --------
    >>> G = nx.DiGraph()
    >>> G.add_edge(1,2)
    >>> list(nx.node_degree_xy(G,x='out',y='in'))
    [(1, 1)]
    >>> list(nx.node_degree_xy(G,x='in',y='out'))
    [(0, 0)]

    Notes
    -----
    For undirected graphs each edge is produced twice, once for each edge 
    representation (u,v) and (v,u), with the exception of self-loop edges 
    which only appear once.
    """
    if nodes is None:
        nodes = set(G)
    else:
        nodes = set(nodes)
    xdeg = G.degree
    ydeg = G.degree
    if G.is_directed():
        direction = {'out':G.out_degree,
                     'in':G.in_degree}
        xdeg = direction[x]
        ydeg = direction[y]

    for u,degu in xdeg(nodes, weight=weight):
        neighbors = (nbr for _,nbr in G.edges(u) if nbr in nodes)
        for v,degv in ydeg(neighbors, weight=weight):
            yield degu,degv
 

# fixture for nose tests
def setup_module(module):
    from nose import SkipTest
    try:
        import numpy
    except:
        raise SkipTest("NumPy not available")
    try:
        import scipy
    except:
        raise SkipTest("SciPy not available")