Search code examples
python-3.xnetworkxigraphshortest-pathnetwork-efficiency

How do I calculate the global efficiency of graph in igraph (python)?


I am trying to calculate the global efficiency of a graph in igraph but I am not sure if I using the module correctly. I think there is a solution that might make a bit of sense but it is in r, and I wasn't able to decipher what they were saying.

I have tried writing the code in a networkx fashion trying to emulate the way they calculate global efficiency but I have been unsuccessful thus far. I am using igraph due to the fact that I am dealing with large graphs. Any help would be really appreciated :D

This is what I have tried:

import igraph
import pandas as pd
import numpy as np
from itertools import permutations

datasafe = pd.read_csv("b1.csv", index_col=0)
D = datasafe.values
g = igraph.Graph.Adjacency((D > 0).tolist())
g.es['weight'] = D[D.nonzero()]

def efficiency_weighted(g):
    weights = g.es["weight"][:]
    eff = (1.0 / np.array(g.shortest_paths_dijkstra(weights=weights)))
    return eff

def global_efficiecny_weighted(g):
    n=180.0
    denom=n*(n-1)
    g_eff = sum(efficiency_weighted(g) for u, v in permutations(g, 2))
    return g_eff

global_efficiecny_weighted(g)

The error message I am getting says:- TypeError: 'Graph' object is not iterable


Solution

  • Assuming that you want the nodal efficiency for all nodes, then you can do this:

    import numpy as np
    from igraph import *
    np.seterr(divide='ignore')
    
    # Example using a random graph with 20 nodes
    g = Graph.Erdos_Renyi(20,0.5)
    
    # Assign weights on the edges. Here 1s everywhere
    g.es["weight"] = np.ones(g.ecount())
    
    def nodal_eff(g):
    
        weights = g.es["weight"][:]
        sp = (1.0 / np.array(g.shortest_paths_dijkstra(weights=weights)))
        np.fill_diagonal(sp,0)
        N=sp.shape[0]
        ne= (1.0/(N-1)) * np.apply_along_axis(sum,0,sp)
    
        return ne
    
    eff = nodal_eff(g)
    print(eff)
    #[0.68421053 0.81578947 0.73684211 0.76315789 0.76315789 0.71052632
    # 0.81578947 0.81578947 0.81578947 0.73684211 0.71052632 0.68421053
    # 0.71052632 0.81578947 0.84210526 0.76315789 0.68421053 0.68421053
    # 0.78947368 0.76315789]
    

    To get the global just do:

    np.mean(eff)