def degree_sequence(network: Network, weight: Weight = None) -> np.array: """Calculates the degree sequence of a network. Parameters ---------- network : Network The :py:class:`Network` object that contains the network weights : bool If True weighted degrees will be calculated Examples -------- Generate a simple network >>> import pathpy as pp >>> net = pp.Network(directed=False) >>> net.add_edge('a', 'b', weight = 2.1) >>> net.add_edge('a', 'c', weight = 1.0) >>> s = pp.algorithms.statistics.degrees.degree_sequence(net) >>> s np.array([2., 1., 1.]) Return weighted degree sequence >>> s = pp.algorithms.statistics.degrees.degree_sequence(net,weight=True) >>> s array([3.1, 2.1, 1.0]) """ _degrees = np.zeros(network.number_of_nodes(), dtype=float) for v in network.nodes.uids: _degrees[network.nodes.index[v]] = network.degrees(weight=weight)[v] return _degrees
def ER_np_randomize(network: Network, loops: bool = False) -> Network: """Generates a random microstate based on the G(n,p) model. The number of nodes, the expected number of edges, the edge directedness and the node uids of the generated network match the corresponding values of a given network instance. """ n = network.number_of_nodes() m = network.number_of_edges() M = max_edges(n, directed=network.directed, loops=loops) p = m/M return ER_np(n=n, p=p, directed=network.directed, loops=loops, node_uids=list(network.nodes.uids))
def ER_nm_randomize(network: Network, loops: bool = False, multiedges: bool = False) -> Union[Network, None]: """Generates a random graph whose number of nodes, edges, edge directedness and node uids match the corresponding values of a given network instance. Useful to generate a randomized version of a network. Parameters ---------- network : pathpy.Network Given network used to determine number of nodes, edges, node uids, and edge directedness loops : bool Whether or not the generated network can contain loops. multi_edge : bool Whether or not multiple edges can be added to the same node pair Examples -------- Generate random undirected network with 10 nodes and 25 edges >>> import pathpy as pp >>> n = pp.Network(directed=False) >>> n.add_edge('a', 'b') >>> n.add_edge('b', 'c') >>> n.add_edge('d', 'e') >>> r = pp.generators.ER_nm(n) >>> print(r) Uid: 0x... Type: Network Directed: False Unique nodes: 5 Unique edges: 3 Unique paths: 0 Total paths: 0 >>> print(r.nodes.uids) { 'a', 'b', 'c', 'd', 'e'} """ return ER_nm(network.number_of_nodes(), network.number_of_edges(), directed=network.directed, loops=loops, multiedges=multiedges, node_uids=list(network.nodes.uids))
def train_test_split(network: Network, test_size: Optional[float] = 0.25, train_size: Optional[float] = None, split: Optional[str] = 'node') -> tuple(Network, Network): """Returns a train/test split of a network object. This method is implemented for instances of Network and TemporalNetwork. The train/test split is non-destructive and based on object references, i.e. the function returns new Network instances that contain references to the same node/edge objects. The original network is not affected. Parameters ---------- network: Union[Network, TemporalNetwork] The network or temporal network for which the train/test split shall be performed. test_size: Optional[float] = 0.25 Fraction of the network to include in the test network train_size: Optional[float] = 0.25 Fraction of the network to include in the training network split: Optional['str'] = 'node' Specifies how the train/test split shall be performed. For 'node' a random subset of nodes is selected, while for 'edge' a random subset of edges is selected. Returns ------- Tuple (n1, n2) where n1 is the training network and n2 is the test network Examples -------- >>> n = pp.Network() >>> n.add_edge('a', 'b') >>> n.add_edge('b', 'c') >>> n.add_edge('c', 'd') >>> n.add_edge('d', 'a') >>> train, test = train_test_split(n, test_size=0.25) >>> print(train) >>> print(test) Network with one node Network with three nodes """ test_network = Network(directed=network.directed, multiedges=network.multiedges, uid=network.uid + '_test') train_network = Network(directed=network.directed, multiedges=network.multiedges, uid=network.uid + '_train') if train_size == None: ts = test_size else: ts = 1.0 - train_size if split == 'node': test_nodes = choice([v.uid for v in network.nodes], size=int(ts * network.number_of_nodes()), replace=False) for v in test_nodes: test_network.add_node(network.nodes[v]) train_nodes = [ v.uid for v in network.nodes if v.uid not in test_network.nodes.uids ] for v in train_nodes: train_network.add_node(network.nodes[v]) for e in network.edges: if e.v.uid in test_network.nodes.uids and e.w.uid in test_network.nodes.uids: test_network.add_edge(e) if e.v.uid in train_network.nodes.uids and e.w.uid in train_network.nodes.uids: train_network.add_edge(e) elif split == 'edge': for v in network.nodes: test_network.add_node(v) train_network.add_node(v) test_edges = choice([e.uid for e in network.edges], size=int(ts * network.number_of_edges()), replace=False) for e in test_edges: test_network.add_edge(network.edges[e]) train_edges = [ e.uid for e in network.edges if e.uid not in test_network.edges.uids ] for e in train_edges: train_network.add_edge(network.edges[e]) else: raise NotImplementedError( 'Unsupported split method "{0}" for instance of type Network'. format(split)) return train_network, test_network