Skip to main content

runlength

Generic run-length encoded sequences in Rust, with plan-based arithmetic. It is the successor to pyrle, with a new API and any value type, not just f64.

Crate Contents
runlength The core: generic Rle<V>, plans, merging, batches, coverage. Depends only on rayon.
runlength-arrow The same over Apache Arrow arrays, so values can be any Arrow type, and batch keys are Arrow tables.
runlength-py The runlength Python package (pyo3). Works with polars, pandas, pyarrow and numpy; none of them is required.

Python

import polars as pl
import runlength as rl

df = pl.DataFrame({
    "Chromosome": ["chr1", "chr1", "chr2"],
    "Strand": ["+", "-", "+"],
    "Start": [0, 2, 5],
    "End": [3, 4, 7],
    "Score": [0.5, 2.0, 1.0],
})
keys = df.select("Chromosome", "Strand")
cov = rl.coverage_by_key(keys, df["Start"], df["End"])  # an RleBatch
cov.get(("chr1", "+"))           # Rle(length=3, runs=1, dtype=Int64) ...
(cov + cov).to_polars()          # Chromosome, Strand, start, end, value
pl.DataFrame(cov.mean())         # Chromosome, Strand, mean
per_chrom = cov.collapse(drop="Strand")          # add the strands together
starts, ends = (per_chrom.get("chr1") > 0).ranges()   # back to intervals
best = rl.coverage_by_key(keys, df["Start"], df["End"], df["Score"], agg="max", fill=None)
cov.slice_agg(keys, df["Start"], df["End"], agg="mean")   # mean coverage per interval, no copies

a = rl.Rle([3, 2], ["x", "y"])              # values of any type
b = rl.Rle([1, 4], pl.Series(["p", "q"]))
a.zip_with(b, lambda x, y: x + y, backend="polars")   # any function, any library
a.plan(b)                                    # or just the plan: (ends, idx_a, idx_b)

Inputs can be polars or pandas Series and DataFrames, pyarrow or numpy arrays, or lists. Outputs (rle.values, rle.runs, batch.keys, ...) speak the Arrow PyCapsule interface, so pl.Series(x), pa.array(x) and np.asarray(x) read them without copying. ==, < etc. are element-wise and return boolean Rles; a.equals(b) compares whole sequences.

Build it locally with cd crates/runlength-py && maturin develop --release.

use runlength::prelude::*;

let a = Rle::from_runs(&[3, 2], vec![1, 2])?;
let b = Rle::from_runs(&[1, 4], vec![10, 20])?;

// The plan only looks at run boundaries...
let p = a.plan_with(&b);
assert_eq!(p.ends, vec![1, 3, 5]);
assert_eq!((p.idx_a, p.idx_b), (vec![0, 0, 1], vec![0, 1, 1]));

// ...so any operation works on any value types.
let labels = a.zip_with(&b, None, None, |x, y| format!("{x}/{y}"))?;

// Operators pad the shorter side with zero and merge the result.
assert_eq!((&a + &b).to_dense(), vec![11, 21, 21, 22, 22]);

What's in it

Area API
Sequences Rle<V> (owned), RleRef<V> (borrowed), shared methods on RleLike
Combining plan, zip_with, zip_with_raw, + - * / & | ^, unary - and !, elem_eq/ne/lt/le/gt/ge
Merging merge, merge_by(pred), merge_mask(mask, Keep), merge_plan(mask), is_merged
Slicing get, slice, getitems (many slices → batch), slice_view and slice_reduce (reduce many slices without copying)
Rearranging shift, reversed, concat, ranges_where
Many inputs plan_many, zip_many
Reductions sum, mean, variance(ddof), std(ddof), min, max (all weighted by run length)
Batches RleBatch<K, V>: many sequences under any hashable keys, joins with How::{Outer, Inner, Left, Right}, collapse, concat, shift, reversed, slice_reduce, parallel with rayon
Coverage coverage_sum, coverage_count, coverage_max, coverage_min (with _by_key variants), and overlap_plan / overlap_plan_by_key for any other aggregation

Conventions

  • Positions are i64; every sequence starts at 0; intervals are [start, end).
  • Neighbouring runs merge when values are identical: NaN merges with NaN, -0.0 does not merge with 0.0.
  • Operations merge by default; _raw variants and plans do not.
  • Combining sequences of different lengths pads the shorter one with a fill value. Operators use zero. With zip_with, passing None makes unequal lengths an error.

See docs/design.md for the reasoning behind these choices.

Development

cargo test                                        # unit, property and doc tests
PROPTEST_CASES=5000 cargo test --release          # more property-test cases
cargo run --release --example bench               # rough timings
cd crates/runlength-py && maturin develop --release && pytest tests

# Regenerate the pyrle cross-check cases (needs a Python that imports pyrle):
PYTHONPATH=~/code/pyrle python3.12 scripts/gen_pyrle_fixtures.py

# Check the reference port of pyranges' to_rle / to_bigwig against
# pyranges1 + pyrle (needs both installed, plus pyBigWig):
PYTHONPATH=~/code/pyrle python scripts/pyranges_port.py 1000

Releasing

Versions of all three crates move together. Bump version in each crates/*/Cargo.toml (and the runlength version that runlength-arrow requires), commit, then push a tag:

git tag py-v0.2.0 && git push origin py-v0.2.0       # wheels + sdist to PyPI
git tag rust-v0.2.0 && git push origin rust-v0.2.0   # runlength, runlength-arrow to crates.io

.github/workflows/release.yml checks that the tag matches the crate versions, builds wheels for Linux (x86_64, aarch64), macOS (universal2) and Windows, tests them, and publishes. Run it by hand from the Actions tab to build and test the wheels without publishing.

One-time setup: add pyranges/runlength with workflow release.yml as a trusted publisher on PyPI, and save a crates.io token as the CARGO_REGISTRY_TOKEN repository secret.

Metadata

Release files for runlength 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for runlength 0.1.0
File Size Uploaded
runlength-0.1.0.tar.gz 126.7 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for runlength 0.1.0
File
runlength-0.1.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
runlength-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl CPython 3.11 abi3 Linux glibc 2.28+ x86-64 Details
runlength-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl CPython 3.11 abi3 Linux glibc 2.28+ ARM64 Details
runlength-0.1.0-cp311-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl CPython 3.11 abi3 macOS 11.0+ ARM64, macOS 10.12+ x86-64, macOS 10.12+ universal2 (ARM64, x86-64) Details

Total release size: 23.7 MB

Release files / runlength-0.1.0.tar.gz

Download URL runlength-0.1.0.tar.gz
Size 126.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2db118d9e71eca6168ead9a2ebfa71827b195a003b86952cbda6a3f4efb13171
BLAKE2b-256 checksum
How to use checksums
1e1201162d63c48861115d9060861b7da6d2d1c0c3dfc6e2af65f052191670bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / runlength-0.1.0-cp311-abi3-win_amd64.whl

Download URL runlength-0.1.0-cp311-abi3-win_amd64.whl
Size 4.5 MB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
35968ee200755db4774805c299cf119f2f7fbff62495887d03e722e25e0f98bd
BLAKE2b-256 checksum
How to use checksums
852f04435ead6bc1013730a4392f1a7cc5b0464ab4505927cd56e12221a5cb10
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / runlength-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl

Download URL runlength-0.1.0-cp311-abi3-manylinux_2_28_x86_64.whl
Size 5.0 MB
Tags CPython 3.11 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
b15ae6c59fce0fb24e92b985ccf732a6b072dd36091b079635dde3f03c0767e5
BLAKE2b-256 checksum
How to use checksums
fc2341094a669140300905c666c81f386059590f14d28e8c116c89d8193cc6da
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / runlength-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl

Download URL runlength-0.1.0-cp311-abi3-manylinux_2_28_aarch64.whl
Size 5.1 MB
Tags CPython 3.11 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
2f7672fa51be8c3715b32cebc0092c239887341268534fae98f5c4f74bb307ec
BLAKE2b-256 checksum
How to use checksums
b23830173c4008e81f1b7df99304241ea8879f48ecc6cc3c502a614da7838a59
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / runlength-0.1.0-cp311-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl

Download URL runlength-0.1.0-cp311-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Size 8.9 MB
Tags CPython 3.11 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
4551f1d3ef714a66128a7e538707294fd0d1f858a47c2af8b6e09d4fe946f964
BLAKE2b-256 checksum
How to use checksums
00819bb19e9e7267bcc0b5c0bb30f78865a29cdebb58507603a2a206730b950c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

5 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page