How to Compute Network Statistics
Goal: Calculate metrics that describe the structure of your multilayer network.
Prerequisites: A loaded network (see How to Load and Build Networks).
Note
Where to find this data
Examples in this guide use:
Programmatically created networks (recommended for self-contained examples)
Built-in generators:
from py3plex.algorithms import random_generatorsExample files:
datasets/multiedgelist.txtin the repository
For reproducibility, we’ll create networks from scratch in most examples.
Quick Statistics
Get an overview of your network:
from py3plex.core import multinet
# Create a multilayer network
network = multinet.multi_layer_network()
network.add_edges([
['A', '1', 'B', '1', 1],
['B', '1', 'C', '1', 1],
['A', '2', 'C', '2', 1],
['C', '2', 'D', '2', 1],
], input_type="list")
# Display comprehensive stats
network.basic_stats()
Expected output:
Number of nodes: 7
Number of edges: 4
Number of unique node IDs (across all layers): 4
Nodes per layer:
Layer '1': 3 nodes
Layer '2': 3 nodes
Layer-Specific Statistics
Compute Per-Layer Density
layers = network.get_layers()
for layer in layers:
# Get nodes and edges in this layer
from py3plex.dsl import Q, L
nodes = Q.nodes().from_layers(L[layer]).execute(network)
edges = Q.edges().from_layers(L[layer]).execute(network)
n = len(nodes)
m = len(edges)
# Density = actual edges / possible edges
max_edges = n * (n - 1) / 2 # undirected
density = m / max_edges if max_edges > 0 else 0
print(f"Layer {layer}: density = {density:.4f}")
Compare Layers
Use the DSL for efficient comparison:
from py3plex.dsl import Q, L
for layer in ["layer1", "layer2", "layer3"]:
result = (
Q.nodes()
.from_layers(L[layer])
.compute("degree")
.execute(network)
)
df = result.to_pandas()
print(f"{layer}: avg degree = {df['degree'].mean():.2f}")
Expected output:
layer1: avg degree = 3.45
layer2: avg degree = 2.87
layer3: avg degree = 4.12
Node-Level Statistics
Node Activity (Layer Count)
How many layers does each node participate in?
from py3plex.dsl import Q
# Get nodes present in multiple layers
active_nodes = (
Q.nodes()
.where(layer_count__gt=1)
.compute("layer_count")
.order_by("-layer_count")
.execute(network)
)
df = active_nodes.to_pandas()
print(df.head(10))
Expected output:
node layer_count
0 Alice 3
1 Bob 3
2 Carol 2
3 Dave 1
Degree Centrality
Compute degree for all nodes:
from py3plex.dsl import Q
result = (
Q.nodes()
.compute("degree")
.order_by("-degree")
.limit(10)
.execute(network)
)
df = result.to_pandas()
print("Top 10 by degree:")
print(df)
Betweenness Centrality
Find nodes that bridge different parts of the network:
result = (
Q.nodes()
.compute("betweenness_centrality")
.order_by("-betweenness_centrality")
.limit(10)
.execute(network)
)
df = result.to_pandas()
print("Top 10 by betweenness:")
print(df)
Multiple Metrics at Once
result = (
Q.nodes()
.compute("degree", "betweenness_centrality", "clustering")
.execute(network)
)
df = result.to_pandas()
print(df.describe())
Multilayer-Specific Statistics
Node Versatility
Versatility measures how evenly a node distributes its connections across layers:
from py3plex.algorithms.statistics import calculate_versatility
versatility_scores = calculate_versatility(network)
# Sort by versatility
sorted_scores = sorted(
versatility_scores.items(),
key=lambda x: x[1],
reverse=True
)
print("Top 5 most versatile nodes:")
for node, score in sorted_scores[:5]:
print(f"{node}: {score:.3f}")
Edge Overlap Between Layers
How many connections exist in multiple layers?
from py3plex.algorithms.statistics import calculate_edge_overlap
overlap = calculate_edge_overlap(network, 'layer1', 'layer2')
print(f"Edge overlap between layer1 and layer2: {overlap:.2%}")
Inter-Layer Degree Correlation
Are high-degree nodes in layer 1 also high-degree in layer 2?
from py3plex.algorithms.statistics import inter_layer_correlation
correlation = inter_layer_correlation(
network,
'layer1',
'layer2',
metric='degree'
)
print(f"Degree correlation: {correlation:.3f}")
Network-Wide Statistics
Global Clustering Coefficient
from py3plex.algorithms.statistics import global_clustering_coefficient
gcc = global_clustering_coefficient(network)
print(f"Global clustering: {gcc:.3f}")
Average Path Length
from py3plex.algorithms.statistics import average_path_length
# Note: computationally expensive for large networks
apl = average_path_length(network)
print(f"Average path length: {apl:.2f}")
Exporting Statistics
Save to CSV
from py3plex.dsl import Q
result = (
Q.nodes()
.compute("degree", "betweenness_centrality", "layer_count")
.execute(network)
)
df = result.to_pandas()
df.to_csv("network_statistics.csv", index=False)
Save to JSON
import json
stats = {
'num_nodes': len(list(network.get_nodes())),
'num_edges': len(list(network.get_edges())),
'num_layers': len(network.get_layers()),
'density_by_layer': {}
}
for layer in network.get_layers():
nodes = Q.nodes().from_layers(L[layer]).execute(network)
edges = Q.edges().from_layers(L[layer]).execute(network)
stats['density_by_layer'][layer] = len(edges) / (len(nodes) ** 2)
with open('stats.json', 'w') as f:
json.dump(stats, f, indent=2)
Common Patterns
Pattern: Compare Node Importance Across Layers
import pandas as pd
layers = network.get_layers()
all_stats = []
for layer in layers:
result = (
Q.nodes()
.from_layers(L[layer])
.compute("degree", "betweenness_centrality")
.execute(network)
)
df = result.to_pandas()
df['layer'] = layer
all_stats.append(df)
combined = pd.concat(all_stats, ignore_index=True)
# Find nodes that are important in all layers
pivot = combined.pivot_table(
values='degree',
index='node',
columns='layer',
aggfunc='mean'
)
print(pivot)
Pattern: Identify Layer-Specific Hubs
for layer in network.get_layers():
result = (
Q.nodes()
.from_layers(L[layer])
.compute("degree")
.order_by("-degree")
.limit(5)
.execute(network)
)
df = result.to_pandas()
print(f"\nTop 5 hubs in {layer}:")
print(df)
Next Steps
Visualize statistics: How to Visualize Multilayer Networks
Find communities: How to Run Community Detection on Multilayer Networks
Understand metrics: Algorithm Landscape
API reference: Algorithm Roadmap