DataFrame & Vulnerability Helpers
The moveq_core.frames module provides high-level DataFrame functions for computing composite demographic vulnerability indices and identifying multiply-deprived spatial cohorts.
moveq-core ultra-lightweight and zero-bloat, DataFrame helpers require the frames extra:
pip install "moveq-core[frames]" (or pip install "moveq[frames]").
1. Vulnerability Index (compute_vulnerability_index)
Normalizes any number of socio-demographic indicators (e.g. % households without a car, % elderly residents, % job seekers) using min-max feature scaling into \([0.0, 1.0]\) and calculates an equal-weighted composite 0-100 vulnerability series:
Python Code Example
import pandas as pd
from moveq_core.frames import compute_vulnerability_index
df = pd.DataFrame({
"zone_id": ["Z1", "Z2", "Z3", "Z4"],
"no_car_pct": [12.0, 45.0, 22.0, 68.0],
"elderly_pct": [10.0, 18.0, 25.0, 12.0],
"unemployment_pct": [3.2, 8.5, 4.1, 14.2]
})
df["vulnerability_score"] = compute_vulnerability_index(
df,
factors=["no_car_pct", "elderly_pct", "unemployment_pct"]
)
print(df[["zone_id", "vulnerability_score"]])
# Returns pandas.Series with 0.0 - 100.0 index scores
2. Identify Multiply-Deprived Zones (identify_multiply_deprived)
Flags spatial zones that simultaneously fall into the worst tertile (top 33.3% most vulnerable) across multiple socio-demographic deprivation indicators:
from moveq_core.frames import identify_multiply_deprived
# Flag rows in the worst tertile for at least 2 out of 3 factors
df["is_multiply_deprived"] = identify_multiply_deprived(
df,
factors=["no_car_pct", "elderly_pct", "unemployment_pct"],
min_factors=2
)
print(df[["zone_id", "is_multiply_deprived"]])
# Returns boolean Series (True for high-priority equity investment zones)
3. GeoPandas & GIS Integration
Because moveq_core.frames operates on standard pandas DataFrames, it integrates seamlessly with geopandas.GeoDataFrame and spatial polygon geometry:
import geopandas as gpd
from moveq_core.frames import compute_vulnerability_index
from moveq import compute_gini
# 1. Load census boundary shapefile / GeoPackage
gdf = gpd.read_file("census_tracts.gpkg")
# 2. Compute vulnerability index column
gdf["vuln_index"] = compute_vulnerability_index(
gdf, factors=["no_vehicle", "low_income_pct", "disability_pct"]
)
# 3. Compute overall service Gini on the GeoDataFrame
gini = compute_gini(gdf["bus_trips"].values, gdf["population"].values)
print(f"Regional Transit Gini: {gini:.4f}")