We build the composite following the OECD/JRC handbook (OECD and European Commission Joint Research Centre 2008): normalize each indicator, weight it, and aggregate. Every choice here is deliberate and logged; ?sec-robustness then tests how much the ranking depends on them.
The pipeline is registry-driven — it reads the same indicators.yml as the rest of the book, so the method described here is the method that runs.
import sys, pathlibsys.path.insert(0, str(pathlib.Path("analysis/pipeline")))from build_index import load_registry, buildimport pandas as pd, numpy as npregistry = load_registry()# Demo data so the book renders before real data lands.rng = np.random.default_rng(0)cols = [i["id"] for i in registry["indicators"]]demo = pd.DataFrame(rng.random((6, len(cols))), index=[f"territory_{i}"for i inrange(1, 7)], columns=cols)result = build(demo, registry)result[["score", "rank"]]
score
rank
territory_1
64.92
1
territory_4
61.51
2
territory_5
51.95
3
territory_3
50.55
4
territory_6
45.85
5
territory_2
45.50
6
Important
The data above is random demo data. No territory is being assessed yet. Real results appear once data/processed/indicators.csv is populated (see Chapter 7 and the data appendix).
TODO: replace min-max + linear aggregation with the chosen normalization and a geometric option; document weights.
OECD, and European Commission Joint Research Centre. 2008. Handbook on Constructing Composite Indicators: Methodology and User Guide. OECD Publishing.