linked
Create and transform graphs
To install: pip install linked
Graph Conversion System
The linked.cast module provides a unified system for converting between different graph data representations. It automatically discovers the shortest conversion path between any two formats.
Quick Start
import numpy as np
from linked import convert_graph
# Convert edge list to nodes_and_links format
edgelist = np.array([[0, 1], [1, 2], [2, 0]])
graph = convert_graph(edgelist, 'nodes_and_links')
# Convert mini-dot to NetworkX (multi-hop conversion)
minidot = "1 -> 2\n2 -> 3"
nx_graph = convert_graph(minidot, 'networkx_graph', from_kind='minidot')
# Convert vectors to graph using k-NN
vectors = np.random.rand(100, 50)
knn_graph = convert_graph(
vectors,
'weighted_edgelist',
from_kind='vectors',
context={'n_neighbors': 15}
)
Supported Formats
nodes_and_links: JSON-style dict (D3.js compatible)edgelist: numpy array (n_edges, 2)weighted_edgelist: numpy array (n_edges, 3)minidot: Simple text formatadjacency_matrix: Dense numpy arraysparse_adjacency: scipy sparse matrixadjacency_list: Dict of neighborsnetworkx_graph: NetworkX Graphnetworkx_digraph: NetworkX DiGraphedges_dataframe: pandas DataFramegraph_dataframes: Dict with edges/nodes DataFramesvectors: numpy array → graph via k-NN
mini_dot_to_graph_jdict
Make graphs from the (mini) dot language.
>>> from linked import mini_dot_to_graph_jdict
>>> mini_dot_to_graph_jdict('''
... 1 -> 2
... 2, 3 -> 5, 6, 7
... ''')
{'nodes': [{'id': '1'},
{'id': '2'},
{'id': '5'},
{'id': '6'},
{'id': '7'},
{'id': '3'}],
'links': [{'source': '1', 'target': '2'},
{'source': '2', 'target': '5'},
{'source': '2', 'target': '6'},
{'source': '2', 'target': '7'},
{'source': '3', 'target': '5'},
{'source': '3', 'target': '6'},
{'source': '3', 'target': '7'}]}
linked.datasrc.vectors
Graph construction from high-dimensional vector data for network analysis and visualization.
This module provides tools to convert point/vector data into graph data (edge lists) suitable for network analysis, visualization, and dimensionality reduction. It focuses on sparse graph construction from large datasets (50K-500K points) with high dimensionality (up to 3000+ features).
Quick Start
import numpy as np
from linked import knn_graph, mutual_knn_graph, adaptive_knn_graph
# Generate sample data
vectors = np.random.rand(1000, 128) # 1000 points, 128 dimensions
# Build a k-NN graph
graph = knn_graph(vectors, n_neighbors=15)
print(graph.shape) # (15000, 3) - source, target, weight
# Build a mutual k-NN graph (more robust for high dimensions)
graph = mutual_knn_graph(vectors, n_neighbors=15, ensure_connectivity="mst")
# Build an adaptive k-NN graph (UMAP-style)
graph = adaptive_knn_graph(vectors, n_neighbors=15, local_connectivity=1)
See more in misc/CAST_README.md.
Graph Construction Methods
1. k-Nearest Neighbors Graph
Connects each point to its k nearest neighbors.
from linked import knn_graph
graph = knn_graph(
vectors,
n_neighbors=15, # Number of neighbors per point
metric="euclidean", # Distance metric
mode="distance", # "distance" or "connectivity"
include_self=False, # Include self-loops
approximate=True, # Use approximate nearest neighbors
n_jobs=-1 # Parallel processing
)
Output Format: Array of shape (n_edges, 3) with columns [source, target, weight] or (n_edges, 2) for connectivity mode.
2. Mutual k-Nearest Neighbors Graph
More robust for high-dimensional data. An edge exists only if both points are in each other's k-NN.
from linked import mutual_knn_graph
graph = mutual_knn_graph(
vectors,
n_neighbors=15,
metric="euclidean",
mode="distance",
approximate=True,
ensure_connectivity="mst", # "none", "mst", or "nn"
n_jobs=-1
)
Connectivity Options:
"none": May result in disconnected components"mst": Add minimum spanning tree edges to ensure connectivity"nn": Connect isolated vertices to their nearest neighbor
3. Epsilon-Neighborhood Graph
Connects all pairs of points within a radius.
from linked import epsilon_graph
graph = epsilon_graph(
vectors,
radius=0.5, # Maximum distance for connections
metric="euclidean",
mode="distance"
)
4. Adaptive k-NN Graph
Uses local density scaling (UMAP-style) to adaptively weight edges based on local structure.
from linked import adaptive_knn_graph
graph = adaptive_knn_graph(
vectors,
n_neighbors=15,
metric="euclidean",
local_connectivity=1, # Min strong connections per point
bandwidth=1.0, # Gaussian kernel bandwidth
approximate=True
)
5. Random Graph Generation
Generate synthetic graphs for testing and benchmarking.
from linked import random_graph
# Erdos-Renyi: random edges with probability p
graph = random_graph(n_nodes=100, model="erdos_renyi", p=0.1, seed=42)
# Barabasi-Albert: preferential attachment
graph = random_graph(n_nodes=100, model="barabasi_albert", m=3, seed=42)
# Watts-Strogatz: small-world network
graph = random_graph(n_nodes=100, model="watts_strogatz", k=6, p=0.1, seed=42)
# Add random weights
graph = random_graph(n_nodes=100, model="erdos_renyi", p=0.1, weighted=True)
Sklearn-Style Estimators
For integration with sklearn pipelines:
from linked import KNNGraphEstimator, MutualKNNGraphEstimator
# Create estimator
estimator = KNNGraphEstimator(n_neighbors=15, approximate=True)
# Fit and transform
graph = estimator.fit_transform(vectors)
Available estimators:
KNNGraphEstimatorMutualKNNGraphEstimatorAdaptiveKNNGraphEstimator
Distance Metrics
All functions support various distance metrics via sklearn:
"euclidean"(default)"manhattan""cosine""minkowski""chebyshev"- And many more from
scipy.spatial.distance
Performance Considerations
Approximate vs. Exact
For large datasets, use approximate=True to enable approximate nearest neighbors via pynndescent:
# Fast approximate search
graph = knn_graph(vectors, n_neighbors=15, approximate=True)
# Slower exact search
graph = knn_graph(vectors, n_neighbors=15, approximate=False)
Approximate methods are typically 10-100x faster with 90-99% accuracy.
Parallel Processing
Use n_jobs=-1 to utilize all CPU cores:
graph = knn_graph(vectors, n_neighbors=15, n_jobs=-1)
Memory Management
For very large datasets (>500K points), consider:
- Using sparse output formats
- Processing in batches
- Using approximate methods
- Reducing
n_neighbors
Output Format
All graph construction functions return numpy arrays:
With weights (mode="distance"):
array([[0, 5, 0.342], # source=0, target=5, weight=0.342
[0, 8, 0.521], # source=0, target=8, weight=0.521
[1, 3, 0.234], # source=1, target=3, weight=0.234
...])
Without weights (mode="connectivity"):
array([[0, 5], # source=0, target=5
[0, 8], # source=0, target=8
[1, 3], # source=1, target=3
...])
Integration with Visualization
Example: Use with force-directed layout:
import numpy as np
from linked import adaptive_knn_graph
import networkx as nx
import matplotlib.pyplot as plt
# Build graph
vectors = np.random.rand(100, 50)
edges = adaptive_knn_graph(vectors, n_neighbors=10)
# Convert to NetworkX
G = nx.Graph()
for source, target, weight in edges:
G.add_edge(int(source), int(target), weight=weight)
# Layout and visualize
pos = nx.spring_layout(G)
nx.draw(G, pos, node_size=50, width=0.5)
plt.show()
Best Practices
-
High-dimensional data: Use
mutual_knn_graphoradaptive_knn_graphfor better structure preservation -
Sparse graphs: Start with smaller
n_neighbors(5-15) and increase if needed -
Connectivity: Use
ensure_connectivity="mst"for visualization tasks -
Large datasets: Enable
approximate=Trueand set appropriaten_jobs -
Distance metrics: Choose based on your data:
- Euclidean: General-purpose, works well for normalized data
- Cosine: Good for high-dimensional sparse data (e.g., text embeddings)
- Manhattan: Robust to outliers
References
The algorithms implemented are based on recent research:
- McInnes et al. (2018): UMAP - Uniform Manifold Approximation and Projection
- Tang et al. (2016): LargeVis - Visualizing Large-scale High-dimensional Data
- Jarvis & Patrick (1973): Clustering Using a Similarity Measure Based on Shared Near Neighbors
- Belkin & Niyogi (2003): Laplacian Eigenmaps
For more details, see the included research document.
Metadata
Release files for linked 0.0.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| linked-0.0.7.tar.gz | 38.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| linked-0.0.7-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 80.8 kB
Release files / linked-0.0.7.tar.gz
| Download URL | linked-0.0.7.tar.gz |
|---|---|
| Size | 38.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
90fcfc13cab1a0d1e1fd7bfa76250796beb76ef9194f0fff969265e456452548
|
|
BLAKE2b-256 checksum How to use checksums |
dfcc1575e52fd201bbed94836d04c58f86f5d084dcc281a2c5266286fff4ba52
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / linked-0.0.7-py3-none-any.whl
| Download URL | linked-0.0.7-py3-none-any.whl |
|---|---|
| Size | 42.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
be3b4d4e8ff6716523648b229ce83cf8a612063d875f1fb7fd9c08c7ab7e033c
|
|
BLAKE2b-256 checksum How to use checksums |
d0b0b2e16d3f76a5ca6061da679b79a1c93a257791d5f9e66d47361da0899ba2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|