ReadMe¶
This notebook is used to compute infrastructure exposure to a set of hazards for a given country and subnational division (admin1 or admin2). It takes as input population and hazard raster files, infrastructure locations and admin boundaries. Output is 7 different spreadsheets (.csv and .xlsx): 1 with all hazards and exposure per infrastructure location; 6 (1 per hazard and current/future) for aggregate number of infrastructure facilities exposed per admin subdivision
Users only need to indicate country 3-letters iso_code (e.g., ‘UKR’ or ‘VNM’), admin level (‘admin2’,‘admin1’) and hazard list. Users can also choose to use default GADM subnational boundaries (instead of a custom subdivision) by setting use_gadm_boundaries = True.
This notebook should be executed after country data preparation (country_data_preparation.ipynb)
All file paths and custom parameters are defined on file constants.py
Custom Functions¶
def process_all_hazards(infrastructure_df,iso_code, admin_level, hazard_list, infrastructure_layer):
"""
Loops over all hazard in hazard_list and compute infrastructure exposure to each one of them.
If no raster is available for a given country / hazard, print a warning message. This
happens when a country is not exposed to a specific hazard (commun for cyclone).
"""
infrastructure_id = GLOBAL_INFRASTRUCTURE_UNIQUE_ID[infrastructure_layer]
admin_pcode = REF_ADMIN_PCODE[admin_level]
infrastructure_exposure_df = pd.DataFrame(infrastructure_df[[admin_pcode, infrastructure_id]])
infrastructure_exposure_df['ISO'] = iso_code
############################
for hazard in hazard_list:
col_name = hazard
exposure_df = pd.DataFrame(infrastructure_df[infrastructure_id])
exposure_df[col_name] = 'no_exposure'
#Loop over all return period for a given hazard (defined on file constants.py)
for return_period in HAZARD_RETURN_PERIOD[hazard]:
try:
new_rp_df = process_infrastructure_exposure_single_hazard(infrastructure_df.copy(),hazard, iso_code, return_period,infrastructure_layer)
exposure_df = exposure_df.merge(new_rp_df, on = infrastructure_id, how = 'left')
#Output value is the lower return period to which the infrastructure is exposed
exposure_df.loc[(exposure_df[col_name] == 'no_exposure') & (exposure_df['value_rp'] == 1),col_name] = str(return_period) + 'yr'
exposure_df.drop(columns = 'value_rp', inplace = True)
except:
#If no raster is available for a given country / hazard, print a warning message.
print('No exposure for hazard ' + hazard + ' - RP-' + str(return_period) + ' on country ' + iso_code)
infrastructure_exposure_df = infrastructure_exposure_df.merge(exposure_df, on = infrastructure_id)
############################
# Create country-specific output path and export data on csv and xlsx formats
infrastructure_exposure_df = infrastructure_exposure_df.round(2)
free_text = infrastructure_layer + '-facilities'
OUTPUT_PATH = ANALYSIS_OUTPUT_PATH.replace('wrl',iso_code.lower()).replace('XXX',free_text)
infrastructure_exposure_df.to_excel(OUTPUT_PATH.replace('.csv','.xlsx'), index=False, sheet_name = free_text)
print(OUTPUT_PATH)
return(infrastructure_exposure_df)
def aggregate_infrastructure_exposure(infrastructure_exposure_df, admin_df, admin_level, hazard, infrastructure_layer):
"""
Computes number of facilities exposed for a given hazard and admin level.
"""
admin_infrastructure_df = admin_df.drop(columns = ['geometry']).copy()
admin_pcode = REF_ADMIN_PCODE[admin_level]
###################################
infrastructure_hazard_df = infrastructure_exposure_df[[admin_pcode, hazard]].copy()
###################################
#Initiate the DataFrame using all possible exposure level (return periods
#for cyclone, flood and earthquake). Initialise all values to 0.
hazard_col_list = hazard_columns_list([hazard])
for col in hazard_col_list:
admin_infrastructure_df[col] = 0
###################################
infrastructure_hazard_df = infrastructure_hazard_df.value_counts().reset_index()
infrastructure_hazard_df.rename(columns = {hazard : 'hazard_value'}, inplace = True)
infrastructure_hazard_df['hazard_value'] = str(hazard) + '_' + infrastructure_hazard_df['hazard_value']
infrastructure_hazard_df = infrastructure_hazard_df.pivot(index=admin_pcode, columns='hazard_value', values='count').reset_index()
admin_infrastructure_df = admin_infrastructure_df.merge(infrastructure_hazard_df, on = admin_pcode, how = 'left', suffixes=('','_new'))
admin_infrastructure_df.fillna(0, inplace = True)
###################################
for col in hazard_col_list:
if col + '_new' in admin_infrastructure_df.columns:
admin_infrastructure_df[col] = admin_infrastructure_df[col + '_new']
admin_infrastructure_df.drop(columns = [col + '_new'], inplace = True)
###################################
admin_infrastructure_df['num_facilities'] = admin_infrastructure_df[hazard_col_list].sum(axis = 1)
admin_infrastructure_df[hazard + '_exposure'] = admin_infrastructure_df['num_facilities'] - admin_infrastructure_df[hazard + '_no_exposure']
###################################
admin_infrastructure_df = admin_infrastructure_df.round(2)
free_text = infrastructure_layer + '-facilities-' + admin_level + '-' + hazard.replace('_','-')
sheet_name_text = infrastructure_layer + '-facilities-' + hazard.replace('_','-')
OUTPUT_PATH = ANALYSIS_OUTPUT_PATH.replace('wrl',iso_code.lower()).replace('XXX',free_text)
admin_infrastructure_df.to_excel(OUTPUT_PATH.replace('.csv','.xlsx'), index=False, sheet_name = sheet_name_text)
print(OUTPUT_PATH)
return(admin_infrastructure_df)
Run code¶
import pandas as pd
from constants import *
from utils import *
########################## USER input ####################
iso_code = 'MOZ'
hazard_list = ['flood_current', 'flood_future', 'cyclone_current', 'cyclone_future', 'earthquake']
infrastructure_list = ['health']
admin_level_list = ['admin1', 'admin2']
use_gadm_boundaries = True
############################################################
for admin_level in admin_level_list:
##Load admin boundary and infrastructure location data
admin_df = load_admin_data(use_gadm_boundaries, iso_code, admin_level)
for infrastructure_layer in infrastructure_list:
infrastructure_df = load_infrastructure_data(iso_code, admin_df, admin_level, infrastructure_layer)
##Process exposure at infrastructure location level
infrastructure_exposure_df = process_all_hazards(infrastructure_df, iso_code, admin_level, hazard_list, infrastructure_layer)
##Aggregate number of exposed infrastructure facilities per admin subdivision
for hazard in hazard_list:
admin_infrastructure_df = aggregate_infrastructure_exposure(infrastructure_exposure_df.copy(), admin_df, admin_level, hazard, infrastructure_layer)