Skip to main content

moveq

Transport-equity analysis for Python.

PyPI Python versions License

moveq turns the numbers you already have — trips per area, population counts, deprivation ranks, coverage shares — into standard inequality measures and a documented composite accessibility score, plus a cross-country catalogue contract so a study cannot silently drop a section when it moves from one country to another.

It is a library stack, not a hosted product. You bring arrays or CSVs; moveq owns the math and the trail of what was computed. It does not decide policy.

This package is the one most people should install. It re-exports the public API of moveq-core and moveq-catalogue behind import moveq. The command-line tool is a separate install: moveq-cli.

What it computes

Inequality of service (who gets how much). Given a service value per area (weekly trips, departures, coverage) and a population weight:

  • Gini — overall inequality of that service across people. 0 is equal service for everyone (including the all-zero convention); values toward 1 mean service is concentrated on a small share of the population. Internally this is a population-weighted Lorenz curve, integrated with the trapezoid rule.
  • Palma ratio — the extremes: mean service of the best-served 10% of the population divided by mean service of the worst-served 40%. Areas that straddle those cuts are split proportionally. Equal service, including all-zero service, yields 1. If the bottom 40% have no service while the top 10% do not, the result is infinity.

Neither Gini nor Palma knows anything about income or deprivation. They only describe the distribution of the service variable.

Inequality along deprivation (who is favoured). The Wagstaff Concentration Index ranks areas by a socioeconomic variable (for example Index of Multiple Deprivation, where 1 is most deprived) and asks whether service rises or falls along that ranking. Tied ranks share a group-midpoint fractional rank so input order does not change the answer. For non-negative service the index lies in [-1, 1]:

  • positive — outcome concentrated among more-advantaged observations (advantage-concentrated)
  • negative — outcome concentrated among less-advantaged observations (disadvantage-concentrated)
  • zero — no systematic gradient with rank

A composite score that does not treat missing data as zero. Accessibility work almost always has holes: night frequency was not collected, weekend service is unknown for one cut. compute_score takes named terms in [0, 1] and design weights. Any term that is None is dropped and the remaining weights are renormalised. The result is a 0–100 score plus a component table (design_weight vs weight_used, which terms were dropped, and a human-readable note). If every term is missing, the score is None rather than a silent 0.

A same / replace / omit registry for multi-country work. When a questionnaire or indicator list is reused in a second country, some items map cleanly, some need a local substitute, and some cannot be measured at small-area resolution. Catalogue requires an explicit decision for every base section so an item cannot disappear without a record.

The methodology guide has the formulae.

Installation

Requires Python 3.10+.

pip install moveq

Pandas helpers for a vulnerability index and “multiply deprived” flags:

pip install "moveq[frames]"

CSV / JSON command line (installs this package as a dependency):

pip install moveq-cli

Quickstart

import numpy as np
from moveq import (
    compute_gini,
    compute_palma_ratio,
    compute_concentration_index,
    gini_result,
    compute_score,
    Catalogue,
    SectionAction,
)

service = np.array([10.0, 20.0, 5.0, 50.0, 8.0])
population = np.array([1000, 800, 1200, 300, 900])
deprivation_rank = np.array([1, 3, 2, 5, 4])  # 1 = most deprived

gini = compute_gini(service, population)
palma = compute_palma_ratio(service, population)
ci = compute_concentration_index(
    service, deprivation_rank, population, rank_direction="higher_is_advantaged"
)
gini_audit = gini_result(service, population)  # EquityResult: value, method, n_areas, …

result = compute_score(
    terms={"coverage": 0.7, "evening": 0.5, "frequency": None, "gap": 0.9},
    weights={"coverage": 0.40, "evening": 0.25, "frequency": 0.20, "gap": 0.15},
)
# result.score is on 0–100; result.dropped lists terms that were None

Package layout

PyPI project Role
moveq (this package) Single import for the Python API
moveq-core NumPy algorithms; optional pandas extras
moveq-catalogue Harmonization registry
moveq-cli moveq command for CSV and JSON

All four are versioned together.

What this stack is not

  • Not a GIS toolkit, GTFS parser, or data pipeline — pass in arrays or CSVs.
  • Not a dashboard or SaaS product.
  • Not a legal or policy verdict. Rankings and cut-offs stay with the analyst.

Documentation

License

BSD 3-Clause.

Metadata

Release files for moveq 0.2.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 moveq 0.2.0
File Size Uploaded
moveq-0.2.0.tar.gz 6.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for moveq 0.2.0
File Interpreter ABI Platform
moveq-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 11.6 kB

Release files / moveq-0.2.0.tar.gz

Download URL moveq-0.2.0.tar.gz
Size 6.0 kB
Tags Source
SHA-256 checksum
How to use checksums
7bec54124a78c47de45ba571468905f4672680abc76160e913044dd5f0dbdb1f
BLAKE2b-256 checksum
How to use checksums
1d2ed9a7c4c1152af9952707f7fd4ca44ac863e7925580db9fb631e66aa88ea8
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 Sep 5, 2026.

Transparency log

Release files / moveq-0.2.0-py3-none-any.whl

Download URL moveq-0.2.0-py3-none-any.whl
Size 5.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
14f89bc7a989e86a721c3ace442b5ec829064b1db6a23f44e140e98c30de2b13
BLAKE2b-256 checksum
How to use checksums
2f20fa208ed01f90473c04c254637b29ec477cda146ee09c4e16e687cb3610fc
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 Sep 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 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