moveq
Transport-equity analysis for Python.
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.
0is equal service for everyone; values toward1mean 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%.
Equal service yields
1. If the bottom 40% have no service at all, 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. The index lies
in [-1, 1]:
- positive — service is concentrated among less deprived areas (pro-rich)
- negative — service is concentrated among more deprived areas (pro-poor)
- 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,
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)
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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file moveq-0.1.1.tar.gz.
File metadata
- Download URL: moveq-0.1.1.tar.gz
- Upload date:
- Size: 5.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3124fd583eabdb8032b132eaa1b32e36a661c481008d7fb6a27c478afcf9a9ca
|
|
| MD5 |
6ef126ce6c2218e432308a1fb72c9b1d
|
|
| BLAKE2b-256 |
f90740fb17d4368f2058a2b8e132b3ac8ff9d97f94c7db3b9e2792ac537a2883
|
Provenance
The following attestation bundles were made for moveq-0.1.1.tar.gz:
Publisher:
publish.yml on SVamseekar/moveq
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
moveq-0.1.1.tar.gz -
Subject digest:
3124fd583eabdb8032b132eaa1b32e36a661c481008d7fb6a27c478afcf9a9ca - Sigstore transparency entry: 2583106792
- Sigstore integration time:
-
Permalink:
SVamseekar/moveq@064f07346e0c48580e898a05fc75d05d6fc78ded -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/SVamseekar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@064f07346e0c48580e898a05fc75d05d6fc78ded -
Trigger Event:
push
-
Statement type:
File details
Details for the file moveq-0.1.1-py3-none-any.whl.
File metadata
- Download URL: moveq-0.1.1-py3-none-any.whl
- Upload date:
- Size: 5.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aecb7ba021be6959224334fce263c86f1a7a73de6439c3aba2b21f06c260c6fa
|
|
| MD5 |
c0075b9861b0f8f2fd9a0812053f6d5f
|
|
| BLAKE2b-256 |
91547b8b018d33c09539e379e18168893877e1c3b2d15b359712b2f4550587fe
|
Provenance
The following attestation bundles were made for moveq-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on SVamseekar/moveq
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
moveq-0.1.1-py3-none-any.whl -
Subject digest:
aecb7ba021be6959224334fce263c86f1a7a73de6439c3aba2b21f06c260c6fa - Sigstore transparency entry: 2583106802
- Sigstore integration time:
-
Permalink:
SVamseekar/moveq@064f07346e0c48580e898a05fc75d05d6fc78ded -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/SVamseekar
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@064f07346e0c48580e898a05fc75d05d6fc78ded -
Trigger Event:
push
-
Statement type: