Skip to main content

Time series to network conversion and analysis

Project description

ts2net

PyPI version Documentation Status Tests License: MIT

Time series to networks. Clean API for visibility graphs, recurrence networks, and transition networks.

Install

Basic Installation

Installs core network builders and sklearn integration:

# Using uv (recommended)
uv pip install ts2net

# Or using pip
pip install ts2net

Optional Feature Tiers

# YAML pipeline CLI + Parquet I/O
uv pip install "ts2net[pipeline]"

# Structural decomposition (BSTS)
uv pip install "ts2net[bsts]"

# Performance acceleration (Numba)
uv pip install "ts2net[speed]"

# All optional features
uv pip install "ts2net[all]"
Extra Includes Use when
(core) numpy, scipy, networkx, sklearn, matplotlib Building networks, sklearn features
[pipeline] click, pyyaml, polars, pyarrow ts2net run, Parquet ingestion
[bsts] statsmodels Structural decomposition
[polars] polars, pyarrow Polars-only ingestion (subset of pipeline)
[speed] numba 100–180× visibility graph speedup
[all] everything above + dtw, cnn, examples, viz Full development setup

Development Installation

For development, use uv:

# Clone the repository
git clone https://github.com/kylejones200/ts2net.git
cd ts2net

# Install with uv (creates virtual environment and installs dependencies)
uv sync --group dev

# Build Rust extension
uv run maturin develop --release

Optional Dependencies

# Using uv
uv pip install "ts2net[pipeline]"   # CLI + Parquet pipeline
uv pip install "ts2net[bsts]"       # BSTS decomposition
uv pip install "ts2net[speed]"      # Performance acceleration (Numba)
uv pip install "ts2net[dtw]"        # DTW distance (tslearn)
uv pip install "ts2net[cnn]"        # Temporal CNN embeddings (PyTorch)
uv pip install "ts2net[examples]"   # Example dependencies
uv pip install "ts2net[all]"        # All optional features

# Or using pip
pip install "ts2net[pipeline]"
pip install "ts2net[bsts]"
pip install "ts2net[speed]"

Verify Installation

import ts2net
print(ts2net.__version__)

from ts2net import HVG
import numpy as np
x = np.random.randn(100)
hvg = HVG()
hvg.build(x)
print(f"Installation successful: {hvg.n_nodes} nodes, {hvg.n_edges} edges")

Quick Start

import numpy as np
from ts2net import HVG

x = np.random.randn(1000)

hvg = HVG()
hvg.build(x)

print(hvg.n_nodes, hvg.n_edges)
print(hvg.degree_sequence())

Adjacency Matrix

A = hvg.adjacency_matrix()
print(A.shape)  # (1000, 1000)

NetworkX (Optional)

NetworkX is optional. Convert only if needed:

G = hvg.as_networkx()
import networkx as nx
print(nx.average_clustering(G))

Structural Decomposition and Residual Topology

For time series with predictable structure (seasonality, trends), decompose first, then analyze the residual:

from ts2net.bsts import features, BSTSSpec

# Decompose and analyze residual in one pass
spec = BSTSSpec(
    level=True,
    trend=False,
    seasonal_periods=[24, 168]  # Daily and weekly for hourly data
)

result = features(x, methods=['hvg', 'transition'], bsts=spec)

# Access three feature blocks
raw_stats = result.raw_stats              # Basic series statistics
structural_stats = result.structural_stats # Component variances, seasonal strength
residual_network_stats = result.residual_network_stats  # Network features from residual

Use cases:

  • Compare meters/wells without seasonal confounds
  • Flag series where structural model fails (high residual complexity)
  • Separate predictable structure from irregular dynamics

Installation: BSTS requires the [bsts] extra (statsmodels is not in the core install):

uv pip install "ts2net[bsts]"
# Or: pip install "ts2net[bsts]"

See examples/bsts_features.py for complete examples.

Large Series

For large series, use output modes to control memory usage:

# Degrees only (most memory efficient)
hvg = HVG(output="degrees")
hvg.build(x)
degrees = hvg.degree_sequence()  # Fast, no edge storage

# Stats only (summary statistics without edges)
hvg = HVG(output="stats")
hvg.build(x)
stats = hvg.stats()  # n_nodes, n_edges, avg_degree, etc.

# Full edges (default, use for small-medium series)
hvg = HVG(output="edges")
hvg.build(x)
edges = hvg.edges  # Full edge list

Scale Guidelines

Series Length Method Recommended Settings Memory Risk
n < 10k All methods output="edges" Safe
10k < n < 100k HVG output="edges" or output="degrees" Safe with sparse
10k < n < 100k NVG limit=2000-5000, output="degrees" Use horizon limit
10k < n < 100k Recurrence rule='knn', k=10-30 Avoid exact all-pairs
n > 100k HVG output="degrees" or output="stats" Safe
n > 100k NVG limit=2000-5000, max_edges=1e6, output="degrees" Required limits
n > 100k Recurrence rule='knn', k=10-30, output="degrees" kNN only

Critical Warnings:

  • Dense adjacency matrices are disabled by default for n > 50k (prevents 63GB+ memory blowup)
  • NVG without limit can create millions of edges for smooth series
  • Recurrence exact all-pairs is O(n²) memory - use kNN for large n
  • NetworkX conversion refused for n > 200k (use force=True to override)

Memory Estimates:

  • Dense adjacency: ~8 * n² bytes (e.g., 90k nodes = 63 GB)
  • Sparse adjacency: ~16 * m bytes where m = edges (e.g., 100k edges = 1.6 MB)
  • Edge list: ~16 * m bytes (similar to sparse)
  • Degrees only: ~8 * n bytes (e.g., 90k nodes = 720 KB)

Methods

Visibility Graphs

HVG - Horizontal Visibility Graph

from ts2net import HVG

hvg = HVG(weighted=False, limit=None)
hvg.build(x)

NVG - Natural Visibility Graph

from ts2net import NVG

# For large series, use horizon limit and bounded work
nvg = NVG(weighted=False, limit=5000, max_edges=1_000_000, output="degrees")
nvg.build(x)

# Or with memory limit
nvg = NVG(limit=2000, max_memory_mb=100)  # Caps at ~100MB
nvg.build(x)

Recurrence Networks

Phase space recurrence:

from ts2net import RecurrenceNetwork

rn = RecurrenceNetwork(m=3, tau=1, rule='knn', k=5)
rn.build(x)

Parameters:

  • m: embedding dimension (None = auto via FNN)
  • tau: time delay
  • rule: 'knn', 'epsilon', 'radius'
  • k: neighbors for k-NN
  • epsilon: threshold for epsilon-recurrence

Transition Networks

Symbolic dynamics:

from ts2net import TransitionNetwork

tn = TransitionNetwork(symbolizer='ordinal', order=3)
tn.build(x)

Symbolizers:

  • 'ordinal': ordinal patterns
  • 'equal_width': equal-width bins
  • 'equal_freq': equal-frequency bins (quantiles)
  • 'kmeans': k-means clustering

Compare Methods

from ts2net import build_network

x = np.random.randn(1000)

for method in ['hvg', 'nvg', 'recurrence', 'transition']:
    if method == 'recurrence':
        g = build_network(x, method, m=3, rule='knn', k=5)
    elif method == 'transition':
        g = build_network(x, method, symbolizer='ordinal', order=3)
    else:
        g = build_network(x, method)
    
    print(f"{method}: {g.n_edges} edges")

Output:

hvg: 1979 edges
nvg: 2931 edges
recurrence: 3159 edges
transition: 18 edges

Multivariate

Multiple time series → network where nodes = time series:

from ts2net.multivariate import ts_dist, net_knn

X = np.random.randn(30, 1000)  # 30 series, 1000 points each

D = ts_dist(X, method='dtw', n_jobs=-1)
G = net_knn(D, k=5)

print(G.n_nodes, G.n_edges)

Distance methods: 'correlation', 'dtw', 'nmi', 'voi', 'es', 'vr'

Network builders: net_knn, net_enn, net_weighted

Performance

With Numba (recommended):

pip install numba

Speedups:

  • HVG: 100x faster
  • NVG: 180x faster
  • Recurrence: 10x faster

API

All methods follow the same pattern:

builder = Method(**params)
builder.build(x)

# Access results
builder.n_nodes
builder.n_edges
builder.edges                # list of tuples
builder.degree_sequence()    # numpy array
builder.adjacency_matrix()   # numpy array
builder.as_networkx()        # optional conversion

Troubleshooting

Common Issues

Memory errors with large time series:

  • Use output="degrees" or output="stats" instead of output="edges"
  • For NVG, always set limit parameter (e.g., limit=5000)
  • For recurrence networks, use rule='knn' with small k (10-30) instead of exact all-pairs

Slow performance:

  • Install Numba: uv pip install numba or pip install numba (100-180x speedup for visibility graphs)
  • Use output="degrees" if you don't need full edge lists
  • For multivariate, use n_jobs=-1 for parallel distance computation

Import errors:

  • Ensure you're using Python 3.12+
  • If Rust extension fails to build, install Rust: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  • For development, run maturin develop --release after installing Rust

NetworkX conversion refused:

  • For very large graphs (n > 200k), NetworkX conversion is disabled by default
  • Use force=True to override: hvg.as_networkx(force=True)
  • Consider using output="degrees" or output="stats" instead

Getting Help

Citation

Multivariate methods based on:

Ferreira, L.N. (2024). From time series to networks in R with the ts2net package. Applied Network Science, 9(1), 32. https://doi.org/10.1007/s41109-024-00642-2

Contributing

Contributions are welcome! See CONTRIBUTING.md for guidelines.

Case Study

Try the Spain smart meter case study in Binder (no dataset download required):

Binder

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ts2net-0.9.0.tar.gz (21.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

ts2net-0.9.0-cp313-cp313-win_amd64.whl (551.7 kB view details)

Uploaded CPython 3.13Windows x86-64

ts2net-0.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (658.2 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

ts2net-0.9.0-cp313-cp313-macosx_11_0_arm64.whl (457.8 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

ts2net-0.9.0-cp312-cp312-win_amd64.whl (551.4 kB view details)

Uploaded CPython 3.12Windows x86-64

ts2net-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (658.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

ts2net-0.9.0-cp312-cp312-macosx_11_0_arm64.whl (457.7 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file ts2net-0.9.0.tar.gz.

File metadata

  • Download URL: ts2net-0.9.0.tar.gz
  • Upload date:
  • Size: 21.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ts2net-0.9.0.tar.gz
Algorithm Hash digest
SHA256 ef84f745e628fe53328bac8f2faf8956810c5c561483429a417285db92a96097
MD5 c7352db5d66042f8f0b935def0ab8a15
BLAKE2b-256 48fd7ba99849e54b91304505f2e686a8f6dc010b4ae68220ddaefe17e7ae467f

See more details on using hashes here.

Provenance

The following attestation bundles were made for ts2net-0.9.0.tar.gz:

Publisher: publish-pypi.yml on kylejones200/ts2net

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ts2net-0.9.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: ts2net-0.9.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 551.7 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ts2net-0.9.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 7414a08346aff5cdc3b1b69056f4da4b98e46d1dc6bd71a6d7cab1e3ca00155e
MD5 8595af40de78547065405fc77360e344
BLAKE2b-256 4fdbcb84f25c7f80121ea8e6788d99e7989380e41bdd534c563fafa1dc930760

See more details on using hashes here.

Provenance

The following attestation bundles were made for ts2net-0.9.0-cp313-cp313-win_amd64.whl:

Publisher: publish-pypi.yml on kylejones200/ts2net

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ts2net-0.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ts2net-0.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b5992a98e96c139e7689cc627ab2d232b6e8e1b331dea9dbf18b124aa6406c96
MD5 b17cfbf0dbda6ed2c334c00d4afccdea
BLAKE2b-256 e32fd9ab96150f87804386216defa07b172aeb97ea0f098a94eb244e9161fea5

See more details on using hashes here.

Provenance

The following attestation bundles were made for ts2net-0.9.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish-pypi.yml on kylejones200/ts2net

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ts2net-0.9.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ts2net-0.9.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fd616b15e63ae9c88653f3c49c9501ce6ef640c0e1a71ecbadab20abeadb6a36
MD5 a695c344b472257263972418497e641f
BLAKE2b-256 22766b3b14f9c4b999d2c69dfa60d171099b6014343cd1cec3eb27cfe101d805

See more details on using hashes here.

Provenance

The following attestation bundles were made for ts2net-0.9.0-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: publish-pypi.yml on kylejones200/ts2net

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ts2net-0.9.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: ts2net-0.9.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 551.4 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ts2net-0.9.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 e1b6910660829e84ec9a7158ee24ca296472d6611a122c994908295f4df684cb
MD5 930848dc398bf552fa292015be88be1b
BLAKE2b-256 9b8be973a42801e25ad0ba632d8c89941caf672521298bceda0de54ca3fe52c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for ts2net-0.9.0-cp312-cp312-win_amd64.whl:

Publisher: publish-pypi.yml on kylejones200/ts2net

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ts2net-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for ts2net-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f5967e5b653f93cae002593ff479903e4e45e2253a3702cffcdb522816d5952a
MD5 7b13301ff9c071cc8b4a4fbb7c203aa2
BLAKE2b-256 33258960273383a1b8c5704af7fb66c7027cdddb991eab87de48937ab94cd805

See more details on using hashes here.

Provenance

The following attestation bundles were made for ts2net-0.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish-pypi.yml on kylejones200/ts2net

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ts2net-0.9.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for ts2net-0.9.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d3267f4e114843dd4b082c42cb514e2ab6ffcdc4b0be648e84dffc408fa67aa8
MD5 3dd2f1f07876b5d86e8f8b5c07a2a310
BLAKE2b-256 c2977653bc85e7798cc9c310306dfb0f7710a3c65bccccba45220b43722fe9d5

See more details on using hashes here.

Provenance

The following attestation bundles were made for ts2net-0.9.0-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: publish-pypi.yml on kylejones200/ts2net

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page