#!/usr/bin/env python import networkx as nx from networkx.algorithms import bipartite from networkx.testing import assert_edges_equal, assert_nodes_equal class TestBipartiteProject: def test_path_projected_graph(self): G = nx.path_graph(4) P = bipartite.projected_graph(G, [1, 3]) assert_nodes_equal(list(P), [1, 3]) assert_edges_equal(list(P.edges()), [(1, 3)]) P = bipartite.projected_graph(G, [0, 2]) assert_nodes_equal(list(P), [0, 2]) assert_edges_equal(list(P.edges()), [(0, 2)]) def test_path_projected_properties_graph(self): G = nx.path_graph(4) G.add_node(1, name='one') G.add_node(2, name='two') P = bipartite.projected_graph(G, [1, 3]) assert_nodes_equal(list(P), [1, 3]) assert_edges_equal(list(P.edges()), [(1, 3)]) assert P.nodes[1]['name'] == G.nodes[1]['name'] P = bipartite.projected_graph(G, [0, 2]) assert_nodes_equal(list(P), [0, 2]) assert_edges_equal(list(P.edges()), [(0, 2)]) assert P.nodes[2]['name'] == G.nodes[2]['name'] def test_path_collaboration_projected_graph(self): G = nx.path_graph(4) P = bipartite.collaboration_weighted_projected_graph(G, [1, 3]) assert_nodes_equal(list(P), [1, 3]) assert_edges_equal(list(P.edges()), [(1, 3)]) P[1][3]['weight'] = 1 P = bipartite.collaboration_weighted_projected_graph(G, [0, 2]) assert_nodes_equal(list(P), [0, 2]) assert_edges_equal(list(P.edges()), [(0, 2)]) P[0][2]['weight'] = 1 def test_directed_path_collaboration_projected_graph(self): G = nx.DiGraph() nx.add_path(G, range(4)) P = bipartite.collaboration_weighted_projected_graph(G, [1, 3]) assert_nodes_equal(list(P), [1, 3]) assert_edges_equal(list(P.edges()), [(1, 3)]) P[1][3]['weight'] = 1 P = bipartite.collaboration_weighted_projected_graph(G, [0, 2]) assert_nodes_equal(list(P), [0, 2]) assert_edges_equal(list(P.edges()), [(0, 2)]) P[0][2]['weight'] = 1 def test_path_weighted_projected_graph(self): G = nx.path_graph(4) P = bipartite.weighted_projected_graph(G, [1, 3]) assert_nodes_equal(list(P), [1, 3]) assert_edges_equal(list(P.edges()), [(1, 3)]) P[1][3]['weight'] = 1 P = bipartite.weighted_projected_graph(G, [0, 2]) assert_nodes_equal(list(P), [0, 2]) assert_edges_equal(list(P.edges()), [(0, 2)]) P[0][2]['weight'] = 1 def test_path_weighted_projected_directed_graph(self): G = nx.DiGraph() nx.add_path(G, range(4)) P = bipartite.weighted_projected_graph(G, [1, 3]) assert_nodes_equal(list(P), [1, 3]) assert_edges_equal(list(P.edges()), [(1, 3)]) P[1][3]['weight'] = 1 P = bipartite.weighted_projected_graph(G, [0, 2]) assert_nodes_equal(list(P), [0, 2]) assert_edges_equal(list(P.edges()), [(0, 2)]) P[0][2]['weight'] = 1 def test_star_projected_graph(self): G = nx.star_graph(3) P = bipartite.projected_graph(G, [1, 2, 3]) assert_nodes_equal(list(P), [1, 2, 3]) assert_edges_equal(list(P.edges()), [(1, 2), (1, 3), (2, 3)]) P = bipartite.weighted_projected_graph(G, [1, 2, 3]) assert_nodes_equal(list(P), [1, 2, 3]) assert_edges_equal(list(P.edges()), [(1, 2), (1, 3), (2, 3)]) P = bipartite.projected_graph(G, [0]) assert_nodes_equal(list(P), [0]) assert_edges_equal(list(P.edges()), []) def test_project_multigraph(self): G = nx.Graph() G.add_edge('a', 1) G.add_edge('b', 1) G.add_edge('a', 2) G.add_edge('b', 2) P = bipartite.projected_graph(G, 'ab') assert_edges_equal(list(P.edges()), [('a', 'b')]) P = bipartite.weighted_projected_graph(G, 'ab') assert_edges_equal(list(P.edges()), [('a', 'b')]) P = bipartite.projected_graph(G, 'ab', multigraph=True) assert_edges_equal(list(P.edges()), [('a', 'b'), ('a', 'b')]) def test_project_collaboration(self): G = nx.Graph() G.add_edge('a', 1) G.add_edge('b', 1) G.add_edge('b', 2) G.add_edge('c', 2) G.add_edge('c', 3) G.add_edge('c', 4) G.add_edge('b', 4) P = bipartite.collaboration_weighted_projected_graph(G, 'abc') assert P['a']['b']['weight'] == 1 assert P['b']['c']['weight'] == 2 def test_directed_projection(self): G = nx.DiGraph() G.add_edge('A', 1) G.add_edge(1, 'B') G.add_edge('A', 2) G.add_edge('B', 2) P = bipartite.projected_graph(G, 'AB') assert_edges_equal(list(P.edges()), [('A', 'B')]) P = bipartite.weighted_projected_graph(G, 'AB') assert_edges_equal(list(P.edges()), [('A', 'B')]) assert P['A']['B']['weight'] == 1 P = bipartite.projected_graph(G, 'AB', multigraph=True) assert_edges_equal(list(P.edges()), [('A', 'B')]) G = nx.DiGraph() G.add_edge('A', 1) G.add_edge(1, 'B') G.add_edge('A', 2) G.add_edge(2, 'B') P = bipartite.projected_graph(G, 'AB') assert_edges_equal(list(P.edges()), [('A', 'B')]) P = bipartite.weighted_projected_graph(G, 'AB') assert_edges_equal(list(P.edges()), [('A', 'B')]) assert P['A']['B']['weight'] == 2 P = bipartite.projected_graph(G, 'AB', multigraph=True) assert_edges_equal(list(P.edges()), [('A', 'B'), ('A', 'B')]) class TestBipartiteWeightedProjection: @classmethod def setup_class(cls): # Tore Opsahl's example # http://toreopsahl.com/2009/05/01/projecting-two-mode-networks-onto-weighted-one-mode-networks/ cls.G = nx.Graph() cls.G.add_edge('A', 1) cls.G.add_edge('A', 2) cls.G.add_edge('B', 1) cls.G.add_edge('B', 2) cls.G.add_edge('B', 3) cls.G.add_edge('B', 4) cls.G.add_edge('B', 5) cls.G.add_edge('C', 1) cls.G.add_edge('D', 3) cls.G.add_edge('E', 4) cls.G.add_edge('E', 5) cls.G.add_edge('E', 6) cls.G.add_edge('F', 6) # Graph based on figure 6 from Newman (2001) cls.N = nx.Graph() cls.N.add_edge('A', 1) cls.N.add_edge('A', 2) cls.N.add_edge('A', 3) cls.N.add_edge('B', 1) cls.N.add_edge('B', 2) cls.N.add_edge('B', 3) cls.N.add_edge('C', 1) cls.N.add_edge('D', 1) cls.N.add_edge('E', 3) def test_project_weighted_shared(self): edges = [('A', 'B', 2), ('A', 'C', 1), ('B', 'C', 1), ('B', 'D', 1), ('B', 'E', 2), ('E', 'F', 1)] Panswer = nx.Graph() Panswer.add_weighted_edges_from(edges) P = bipartite.weighted_projected_graph(self.G, 'ABCDEF') assert_edges_equal(list(P.edges()), Panswer.edges()) for u, v in list(P.edges()): assert P[u][v]['weight'] == Panswer[u][v]['weight'] edges = [('A', 'B', 3), ('A', 'E', 1), ('A', 'C', 1), ('A', 'D', 1), ('B', 'E', 1), ('B', 'C', 1), ('B', 'D', 1), ('C', 'D', 1)] Panswer = nx.Graph() Panswer.add_weighted_edges_from(edges) P = bipartite.weighted_projected_graph(self.N, 'ABCDE') assert_edges_equal(list(P.edges()), Panswer.edges()) for u, v in list(P.edges()): assert P[u][v]['weight'] == Panswer[u][v]['weight'] def test_project_weighted_newman(self): edges = [('A', 'B', 1.5), ('A', 'C', 0.5), ('B', 'C', 0.5), ('B', 'D', 1), ('B', 'E', 2), ('E', 'F', 1)] Panswer = nx.Graph() Panswer.add_weighted_edges_from(edges) P = bipartite.collaboration_weighted_projected_graph(self.G, 'ABCDEF') assert_edges_equal(list(P.edges()), Panswer.edges()) for u, v in list(P.edges()): assert P[u][v]['weight'] == Panswer[u][v]['weight'] edges = [('A', 'B', 11 / 6.0), ('A', 'E', 1 / 2.0), ('A', 'C', 1 / 3.0), ('A', 'D', 1 / 3.0), ('B', 'E', 1 / 2.0), ('B', 'C', 1 / 3.0), ('B', 'D', 1 / 3.0), ('C', 'D', 1 / 3.0)] Panswer = nx.Graph() Panswer.add_weighted_edges_from(edges) P = bipartite.collaboration_weighted_projected_graph(self.N, 'ABCDE') assert_edges_equal(list(P.edges()), Panswer.edges()) for u, v in list(P.edges()): assert P[u][v]['weight'] == Panswer[u][v]['weight'] def test_project_weighted_ratio(self): edges = [('A', 'B', 2 / 6.0), ('A', 'C', 1 / 6.0), ('B', 'C', 1 / 6.0), ('B', 'D', 1 / 6.0), ('B', 'E', 2 / 6.0), ('E', 'F', 1 / 6.0)] Panswer = nx.Graph() Panswer.add_weighted_edges_from(edges) P = bipartite.weighted_projected_graph(self.G, 'ABCDEF', ratio=True) assert_edges_equal(list(P.edges()), Panswer.edges()) for u, v in list(P.edges()): assert P[u][v]['weight'] == Panswer[u][v]['weight'] edges = [('A', 'B', 3 / 3.0), ('A', 'E', 1 / 3.0), ('A', 'C', 1 / 3.0), ('A', 'D', 1 / 3.0), ('B', 'E', 1 / 3.0), ('B', 'C', 1 / 3.0), ('B', 'D', 1 / 3.0), ('C', 'D', 1 / 3.0)] Panswer = nx.Graph() Panswer.add_weighted_edges_from(edges) P = bipartite.weighted_projected_graph(self.N, 'ABCDE', ratio=True) assert_edges_equal(list(P.edges()), Panswer.edges()) for u, v in list(P.edges()): assert P[u][v]['weight'] == Panswer[u][v]['weight'] def test_project_weighted_overlap(self): edges = [('A', 'B', 2 / 2.0), ('A', 'C', 1 / 1.0), ('B', 'C', 1 / 1.0), ('B', 'D', 1 / 1.0), ('B', 'E', 2 / 3.0), ('E', 'F', 1 / 1.0)] Panswer = nx.Graph() Panswer.add_weighted_edges_from(edges) P = bipartite.overlap_weighted_projected_graph(self.G, 'ABCDEF', jaccard=False) assert_edges_equal(list(P.edges()), Panswer.edges()) for u, v in list(P.edges()): assert P[u][v]['weight'] == Panswer[u][v]['weight'] edges = [('A', 'B', 3 / 3.0), ('A', 'E', 1 / 1.0), ('A', 'C', 1 / 1.0), ('A', 'D', 1 / 1.0), ('B', 'E', 1 / 1.0), ('B', 'C', 1 / 1.0), ('B', 'D', 1 / 1.0), ('C', 'D', 1 / 1.0)] Panswer = nx.Graph() Panswer.add_weighted_edges_from(edges) P = bipartite.overlap_weighted_projected_graph(self.N, 'ABCDE', jaccard=False) assert_edges_equal(list(P.edges()), Panswer.edges()) for u, v in list(P.edges()): assert P[u][v]['weight'] == Panswer[u][v]['weight'] def test_project_weighted_jaccard(self): edges = [('A', 'B', 2 / 5.0), ('A', 'C', 1 / 2.0), ('B', 'C', 1 / 5.0), ('B', 'D', 1 / 5.0), ('B', 'E', 2 / 6.0), ('E', 'F', 1 / 3.0)] Panswer = nx.Graph() Panswer.add_weighted_edges_from(edges) P = bipartite.overlap_weighted_projected_graph(self.G, 'ABCDEF') assert_edges_equal(list(P.edges()), Panswer.edges()) for u, v in list(P.edges()): assert P[u][v]['weight'] == Panswer[u][v]['weight'] edges = [('A', 'B', 3 / 3.0), ('A', 'E', 1 / 3.0), ('A', 'C', 1 / 3.0), ('A', 'D', 1 / 3.0), ('B', 'E', 1 / 3.0), ('B', 'C', 1 / 3.0), ('B', 'D', 1 / 3.0), ('C', 'D', 1 / 1.0)] Panswer = nx.Graph() Panswer.add_weighted_edges_from(edges) P = bipartite.overlap_weighted_projected_graph(self.N, 'ABCDE') assert_edges_equal(list(P.edges()), Panswer.edges()) for u, v in P.edges(): assert P[u][v]['weight'] == Panswer[u][v]['weight'] def test_generic_weighted_projected_graph_simple(self): def shared(G, u, v): return len(set(G[u]) & set(G[v])) B = nx.path_graph(5) G = bipartite.generic_weighted_projected_graph(B, [0, 2, 4], weight_function=shared) assert_nodes_equal(list(G), [0, 2, 4]) assert_edges_equal(list(list(G.edges(data=True))), [(0, 2, {'weight': 1}), (2, 4, {'weight': 1})]) G = bipartite.generic_weighted_projected_graph(B, [0, 2, 4]) assert_nodes_equal(list(G), [0, 2, 4]) assert_edges_equal(list(list(G.edges(data=True))), [(0, 2, {'weight': 1}), (2, 4, {'weight': 1})]) B = nx.DiGraph() nx.add_path(B, range(5)) G = bipartite.generic_weighted_projected_graph(B, [0, 2, 4]) assert_nodes_equal(list(G), [0, 2, 4]) assert_edges_equal(list(G.edges(data=True)), [(0, 2, {'weight': 1}), (2, 4, {'weight': 1})]) def test_generic_weighted_projected_graph_custom(self): def jaccard(G, u, v): unbrs = set(G[u]) vnbrs = set(G[v]) return float(len(unbrs & vnbrs)) / len(unbrs | vnbrs) def my_weight(G, u, v, weight='weight'): w = 0 for nbr in set(G[u]) & set(G[v]): w += G.edges[u, nbr].get(weight, 1) + G.edges[v, nbr].get(weight, 1) return w B = nx.bipartite.complete_bipartite_graph(2, 2) for i, (u, v) in enumerate(B.edges()): B.edges[u, v]['weight'] = i + 1 G = bipartite.generic_weighted_projected_graph(B, [0, 1], weight_function=jaccard) assert_edges_equal(list(G.edges(data=True)), [(0, 1, {'weight': 1.0})]) G = bipartite.generic_weighted_projected_graph(B, [0, 1], weight_function=my_weight) assert_edges_equal(list(G.edges(data=True)), [(0, 1, {'weight': 10})]) G = bipartite.generic_weighted_projected_graph(B, [0, 1]) assert_edges_equal(list(G.edges(data=True)), [(0, 1, {'weight': 2})])