Skip to content
Finding core-periphery pairs across various resolution scales.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


About this library

A Python wrapper for the c++ code of the algorithm to detect core-periphery pairs in networks generated by one-mode projection of bipartite networks.

Please cite:

Sadamori Kojaku, Mengqiao Xu, Haoxiang Xia and Naoki Masuda. Multiscale core-periphery structure in a global liner shipping network. Preprint arXiv: 1808.04549.


Python code:
  • multiresolcp/
  • multiresolcp/
C++ code:
  • include/km_omp.h
  • include/km_multiresol.h
  • include/graph.h
Python - C++ interface:
  • src/_km_omp.cpp
Example data and code:
  • example/
  • example/data/edge-list.dat
Others (for PyPi registration and Travis-CI):
  • requirements.txt
  • .travis.yml
  • tests


To install, type

pip3 install multiresolcp

If you don't have root privilege, use -user flag, i.e.,

pip3 install --user multiresolcp


import multiresolcp
c, x = multiresolcp.detect(G, nodes_in_part1, nodes_in_part2, part_to_project, resol, node_capacity, num_samples, consensus_threshold, significance_level, num_rand_nets)


G: NetworkX graph object
  • Unweighted bipartite network composed of N nodes in part 1 and M nodes in part 2
  • Node's name can be string or number.
  • Nodes in the same part should not be adjacent to each other.
nodes_in_part1: list of length N
  • List of all nodes' names in part 1
nodes_in_part2: list of length M
  • List of all nodes' names in part 2
part_to_project: string
  • Specify the part to project onto (set either part_to_project='part1' or part_to_project='part2')
resol : float (Optional; Default resol = 1; 0<=resol)
  • Resolution parameter
node_capacity : dict (Optional; Default node_capacity[r] = 1 for all r)
  • key : node's name (string or number). If part_to_project = 'part1', then set key to the names of nodes in part 2. If part_to_project = 'part2', then set key to the names of nodes in part 1.
  • value : node_capacity of node. node_capacity is used to set the weight of edges in the projected network. If part_to_project = 'part1', we place an edge between each pair of nodes in part 1 that have at least one common neighbour in the bipartite network. Then, we set the weight of the edge by summing 'node_capacity[r]' / (degree[r] -1) over all common neighbours r, where degree[r] is the degree of node r in the bipartite network. If part_to_project = 'part2', we carry out the same procedure for nodes in part 2.
num_samples: int (Optional; Default num_samples = 100; 0 < num_samples)
  • Number of optimisation runs carries out for the given network. num_samples is used for the consensus clustering.
consensus_threshold: float (Optional; Default consensus_threshold = 0.9; 0 <= consensus_threshold <=1)
  • Consensus threshold. If two nodes belong to the same CP pair in at least 'consensus_threshold' * 'num_samples' optimisation runs out of the 'num_samples' optimisation runs carried out for the given network, the consensus clustering regards that the two nodes belong to the same CP pair.
significance_level: float (Optional; Default significance_level = 0.05; 0 < significance_level <=1)
  • Statistical significance level before the Šidák correction
num_rand_nets: int (Optional; Default num_rand_nets = 500; 0 < num_rand_nets)
  • Number of randomised networks used to test the statistical significance


c: dict
  • key: node's name
  • value: index of the consensus CP pair to which the node belongs (the index starts from zero)
x: dict
  • key: node's name
  • value: coreness of the node

Note that c and x only contain the nodes in the consensus CP pairs. If c and x do not contain some nodes, it means that the missing nodes do not belong to any consensus CP pair. If too few nodes are contained in c and x, try decreasing the consensus threshold (i.e., consensus_threshold).


In this example, we construct a network of nodes in part 1 using a one-mode projection. Then, we detect core-periphery structure in the projected network across different resolutions.

Example code and data are located in ./example directory.

import networkx as nx
import numpy as np
import pandas as pd
import multiresolcp as mcp

df = pd.read_csv('data/edge-list.dat', sep=' ') # Load a list of edges (space-separated file)

G = nx.from_pandas_edgelist(df) # NetworkX graph object

part1 = df['source'].unique().tolist() # List of nodes in part 1
part2 = df['target'].unique().tolist() # List of nodes in part 2

for resolution in [0.01, 0.1, 0.5, 1, 1.5, 2]:

        c, x = mcp.detect(G, part1, part2, part_to_project = 'part1', resol = resolution) # Detect core-periphery structure at 'resolution'

        # Show results
        print('resolution = %f' % resolution)
        print('c:', c)
        print('x:', x)


  • Python 3.4 or later
  • Numpy 1.14 or later
  • SciPy 1.1 or later
  • NetworkX 2.0 or later
  • pybind11 2.2 or later
You can’t perform that action at this time.