2424import json
2525import logging
2626import shutil
27- import zipfile
28- from pathlib import Path
2927
3028import numpy as np
3129import pandas as pd
3735
3836LOGGER = logging .getLogger (__name__ )
3937
40- WORLD_BANK_WEALTH_ACC = (
41- "https://databank.worldbank.org/data/download/Wealth-Accounts_CSV.zip"
42- )
43- """Wealth historical data (1995, 2000, 2005, 2010, 2014) from World Bank (ZIP).
44- https://datacatalog.worldbank.org/dataset/wealth-accounting
45- Includes variable Produced Capital (NW.PCA.TO)"""
46-
47- FILE_WORLD_BANK_WEALTH_ACC = "Wealth-AccountsData.csv"
48-
4938WORLD_BANK_INC_GRP = "https://ddh-openapi.worldbank.org/resources/DR0095334/download"
5039"""Income group historical data from World bank."""
5140
@@ -204,19 +193,20 @@ def download_world_bank_indicator(
204193 pages = np .inf
205194 page = 1
206195 while page <= pages :
207- response = requests . get (
196+ url = (
208197 f"https://api.worldbank.org/v2/countries/{ country_code } /indicators/"
209- f"{ indicator } ?format=json&page={ page } " ,
210- timeout = 30 ,
198+ f"{ indicator } ?format=json&page={ page } "
211199 )
200+ response = requests .get (url , timeout = 30 )
212201 json_data = json .loads (response .text )
213202
214203 # Check if we received an error message
215204 try :
216205 if json_data [0 ]["message" ][0 ]["id" ] == "120" :
217206 raise ValueError (
218207 "Error requesting data from the World Bank API. Did you use the "
219- "correct country code and indicator ID?"
208+ "correct country code and indicator ID?\n "
209+ f"{ url } "
220210 )
221211 # If no, we should be fine
222212 except KeyError :
@@ -413,9 +403,9 @@ def world_bank_wealth_account(
413403 cntry_iso , ref_year , variable_name = "NW.PCA.TO" , no_land = True
414404):
415405 """
416- Download and unzip wealth accounting historical data (1995, 2000, 2005, 2010, 2014)
417- from World Bank (https://datacatalog.worldbank.org/dataset/wealth-accounting ).
418- Return requested variable for a country (cntry_iso) and a year (ref_year).
406+ Download wealth accounting data from the World Bank API and return the requested
407+ variable for a country (cntry_iso) and a year (ref_year ).
408+ https://datacatalog.worldbank.org/search/dataset/0042066
419409
420410 Parameters
421411 ----------
@@ -424,10 +414,9 @@ def world_bank_wealth_account(
424414 ref_year : int
425415 reference year
426416
427- * available in data: 1995, 2000, 2005, 2010, 2014
428- * other years between 1995 and 2014 are interpolated
429- * for years outside range, indicator is scaled
430- proportionally to GDP
417+ * available in data: 1995-2020
418+ * years within the data range are interpolated
419+ * for years outside range, indicator is scaled proportionally to GDP
431420
432421 variable_name : str
433422 select one variable, i.e.:
@@ -454,57 +443,46 @@ def world_bank_wealth_account(
454443 (applies to 'NW.PCA.*' only). Default: True.
455444 """
456445 try :
457- data_file = SYSTEM_DIR .joinpath (FILE_WORLD_BANK_WEALTH_ACC )
458- if not data_file .is_file ():
459- data_file = SYSTEM_DIR .joinpath (
460- "Wealth-Accounts_CSV" , FILE_WORLD_BANK_WEALTH_ACC
461- )
462- if not data_file .is_file ():
463- if not SYSTEM_DIR .joinpath ("Wealth-Accounts_CSV" ).is_dir ():
464- SYSTEM_DIR .joinpath ("Wealth-Accounts_CSV" ).mkdir ()
465- file_down = download_file (WORLD_BANK_WEALTH_ACC )
466- zip_ref = zipfile .ZipFile (file_down , "r" )
467- zip_ref .extractall (SYSTEM_DIR .joinpath ("Wealth-Accounts_CSV" ))
468- zip_ref .close ()
469- Path (file_down ).unlink ()
470- LOGGER .debug ("Download and unzip complete. Unzipping %s" , str (data_file ))
471-
472- data_wealth = pd .read_csv (data_file , sep = "," , index_col = None , header = 0 )
473- except Exception as err :
474- raise type (err )(
475- "Downloading World Bank Wealth Accounting Data failed: " + str (err )
476- ) from err
477-
478- data_wealth = data_wealth [
479- data_wealth ["Country Code" ].str .contains (cntry_iso )
480- & data_wealth ["Indicator Code" ].str .contains (variable_name )
481- ].loc [:, "1995" :"2014" ]
482- years = list (map (int , list (data_wealth )))
483- if (
484- data_wealth .size == 0 and "NW.PCA.TO" in variable_name
485- ): # if country is not found in data
446+ data_wealth = download_world_bank_indicator (
447+ country_code = cntry_iso ,
448+ indicator = variable_name ,
449+ ).dropna ()
450+ except ValueError :
451+ data_wealth = pd .Series (dtype = float )
452+
453+ if data_wealth .empty and "NW.PCA.TO" in variable_name :
486454 LOGGER .warning (
487455 "No data available for country. Using non-financial wealth instead"
488456 )
489457 gdp_year , gdp_val = gdp (cntry_iso , ref_year )
490458 fac = wealth2gdp (cntry_iso )[1 ]
491459 return gdp_year , np .around ((fac * gdp_val ), 1 ), 0
492- if ref_year in years : # indicator for reference year is available directly
493- result = data_wealth .loc [:, str (ref_year )].values [0 ]
494- elif np .min (years ) < ref_year < np .max (years ): # interpolate
495- result = np .interp (ref_year , years , data_wealth .values [0 , :])
496- elif ref_year < np .min (years ): # scale proportionally to GDP
460+
461+ years = data_wealth .index .values
462+ if ref_year in years :
463+ result = data_wealth .loc [ref_year ]
464+ elif np .min (years ) < ref_year < np .max (years ):
465+ result = np .interp (ref_year , years , data_wealth .values )
466+ elif ref_year < np .min (years ):
497467 gdp_year , gdp0_val = gdp (cntry_iso , np .min (years ))
498468 gdp_year , gdp_val = gdp (cntry_iso , ref_year )
499- result = data_wealth .values [0 , 0 ] * gdp_val / gdp0_val
469+ result = (
470+ data_wealth .iloc [data_wealth .index .get_loc (np .min (years ))]
471+ * gdp_val
472+ / gdp0_val
473+ )
500474 ref_year = gdp_year
501475 else :
502476 gdp_year , gdp0_val = gdp (cntry_iso , np .max (years ))
503477 gdp_year , gdp_val = gdp (cntry_iso , ref_year )
504- result = data_wealth .values [0 , - 1 ] * gdp_val / gdp0_val
478+ result = (
479+ data_wealth .iloc [data_wealth .index .get_loc (np .max (years ))]
480+ * gdp_val
481+ / gdp0_val
482+ )
505483 ref_year = gdp_year
484+
506485 if "NW.PCA." in variable_name and no_land :
507- # remove value of built-up land from produced capital
508486 result = result / 1.24
509487 return ref_year , np .around (result , 1 ), 1
510488
0 commit comments