Skip to content

fix(finance): handle missing World Bank indicators and fallback ISO codes (#1331) - #1349

Open
napattan wants to merge 2 commits into
CLIMADA-project:developfrom
napattan:fix/issue-1331-worldbank-missing-indicators
Open

napattan wants to merge 2 commits into
CLIMADA-project:developfrom
napattan:fix/issue-1331-worldbank-missing-indicators

Conversation

@napattan

@napattan napattan commented Nov 6, 2026 •

Copy link
Copy Markdown

Changes proposed in this PR:

  • Raise a descriptive ValueError in world_bank() (climada/util/finance.py) when download_world_bank_indicator() returns an all-NaN series (close_val.empty after .dropna()), and include ValueError in income_group()'s fallback exception tuple so missing World Bank income group rows fall back cleanly to nat_earth_adm0().
  • Extend nat_earth_adm0() in climada/util/finance.py to check fallback ISO code attributes ("ADM0_A3", "ISO_A3", "WB_A3", "ADM0_A3_US") (resolving ESH and ALA lookup failures in missing worldbank indicators #1331) and distinguish missing country records (close_val is None) from legitimate 0.0 GDP records (such as HMD), logging a warning when Natural Earth reports 0.
  • Guard world_bank_wealth_account() in climada/util/finance.py against all-NaN NW.PCA.TO indicator series and np.isnan(fac) when wealth2gdp() returns (None, np.nan), falling back to fac = 1.0 with a warning instead of propagating NaN.
  • Add unit tests in climada/util/test/test_finance.py (test_ne_fallback_iso_and_zero_gdp_pass, test_wb_empty_indicator_raises_value_error, test_pca_missing_wealth2gdp_factor_pass).

Reproducible Verification Script (#1331)

Below is a self-contained script verifying all four failure modes reported in #1331 (world_bank empty indicator ValueError, income_group fallback to Natural Earth, nat_earth_adm0 fallback ISO attributes & zero-GDP handling, and world_bank_wealth_account NaN wealth-to-GDP factor fallback):

from unittest.mock import patch
import numpy as np
import pandas as pd
from climada.util.finance import (
    _nat_earth_shp,
    income_group,
    nat_earth_adm0,
    world_bank,
    world_bank_wealth_account,
)

shp_file = _nat_earth_shp("10m", "cultural", "admin_0_countries")

# 1. Fallback ISO attributes (ESH under WB_A3/ADM0_A3_US, ALA under ISO_A3) & 0.0 GDP (HMD)
yr_esh, val_esh = nat_earth_adm0("ESH", "GDP_MD", "GDP_YEAR", shp_file=shp_file)
yr_ala, val_ala = nat_earth_adm0("ALA", "INCOME_GRP", shp_file=shp_file)
yr_hmd, val_hmd = nat_earth_adm0("HMD", "GDP_MD", "GDP_YEAR", shp_file=shp_file)
print(f"1. nat_earth_adm0: ESH=({yr_esh}, {val_esh}), ALA=({yr_ala}, {val_ala}), HMD=({yr_hmd}, {val_hmd})")
assert (yr_esh, val_esh) == (2007, 9.07e08)
assert (yr_ala, val_ala) == (0, 4)
assert (yr_hmd, val_hmd) == (2016, 0.0)

# 2. All-NaN World Bank indicator raises ValueError (and income_group falls back to Natural Earth)
empty_series = pd.Series([np.nan, np.nan], index=[2019, 2020])
with patch("climada.util.finance.download_world_bank_indicator", return_value=empty_series):
    try:
        world_bank("GIB", 2020, "NY.GDP.MKTP.CD")
    except ValueError as err:
        print(f"2. world_bank all-NaN raised expected ValueError: {err}")
    ig_yr, ig_val = income_group("ALA", 2020, shp_file=shp_file)
    print(f"3. income_group('ALA', 2020) fallback -> year={ig_yr}, group={ig_val}")
    assert ig_val == 4

# 3. Missing wealth2gdp factor (NaN) falls back cleanly without returning NaN
with patch("climada.util.finance.download_world_bank_indicator", return_value=empty_series), \
     patch("climada.util.finance.wealth2gdp", return_value=(None, np.nan)), \
     patch("climada.util.finance.gdp", return_value=(2015, 5.0e10)):
    wb_yr, wb_val, q = world_bank_wealth_account("LBY", 2015, no_land=True)
    print(f"4. world_bank_wealth_account('LBY', 2015) fallback -> year={wb_yr}, val={wb_val}, q={q}")
    assert q == 0 and not np.isnan(wb_val)

This PR fixes #1331

PR Author Checklist

PR Reviewer Checklist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant