Shock and scenario analysis
Scenario Analysis and Shock Implementation in MARIO¶
Implementing a shock without using mario excel platform¶
A scenario can be implemented in multiple ways within mario. Simple shocks may be implemented with mario as follow:
from mario import load_test, slicer
# loading the baseline scenario (using the load_test)
test = load_test('IOT')
# In order to implement a scenario with respect to the baseline, we can clone the baseline database using the clone function
# and creating a new scenario
test.clone_scenario(
scenario='baseline', # from which scenario clone
name='Final demand increase',# what will be the name of the new scenario
)
#checking the scenarios of the model
print(test.scenarios)
['baseline', 'Final demand increase']
lets increase the local final demand of Italy by 10%
# using the loc function of pd.DataFrames, we can implement a change in the final demand of the new scenario
# we may use the slicer function to do it easily
Y_rows = slicer(matrix='Y',axis= 0,Region=['Italy'],Item=['Agriculture'])
Y_cols = slicer(matrix='Y',axis= 1,Region=['Italy'],Item=['Final Demand'])
Y_new = test.matrices['Final demand increase']['Y']
Y_new.loc[Y_rows,Y_cols]*=1.1
# updating the matrix using the update function to track in the metadata
test.update_scenarios(scenario='Final demand increase',Y=Y_new)
# as the new scenario is cloning all the data from baseline, we need to reset the new scenario to coefficients and re calculte
# all the flows
test.reset_to_coefficients(scenario='Final demand increase')
# now using the get_data function, we can see the change in the different matrices. For example:
delta_X = test.get_data(
matrices=['X'],
scenarios= ['Final demand increase'],
base_scenario = 'baseline', # requsting the differential results for matrix X between two scenarios,
format= 'dict',# asking the results in form of a dictionary,
indeces=False,# not intrested at looking at the units information
units=False, # not intrested at lookning database information
)
# looking at the changes
print(delta_X)
{'Final demand increase': {'X': production Region Level Item Italy Sector Agriculture 2961.338965 Construction 57.329630 Manufacturing 597.267115 Mining 6.332699 Services 745.379267 Transport 185.686254 RoW Sector Agriculture 121.156060 Construction 5.421589 Manufacturing 302.857308 Mining 45.949173 Services 193.241123 Transport 36.432992}}
# the output of the get_data function is a comprehensive data on the all the scenarios and matrices asked
print(delta_X['Final demand increase']['X'])
production Region Level Item Italy Sector Agriculture 2961.338965 Construction 57.329630 Manufacturing 597.267115 Mining 6.332699 Services 745.379267 Transport 185.686254 RoW Sector Agriculture 121.156060 Construction 5.421589 Manufacturing 302.857308 Mining 45.949173 Services 193.241123 Transport 36.432992
# The plot_matrix function can be used to plot the changes of the X
test.plot_matrix(
matrix='X', # plotting the X matrix
x='Region_from', # putting the origin regions on the X axis
color='Sector_from', # colors are defined tby the origin sectors
base_scenario='baseline', # printing the delta_x with respect to baseline scenario,
path = 'delta_X.html'
)
Implementing a shock using mario excel platform¶
mario also supports introduction of very complex shocks through an excel platform, which can be generated with mario automatically based on the shape of the database. Then scenarios can be translated with the options of the excel files.
The excel platform alos gives the opprotunity to define cluseters of sets like Region, Secotr,.... to implement more complex shocks
# Simple shock implementation without clusters
test= load_test('IOT')
# request mario to create the excel file for implementing the shocks
save_path = r'shock_iot.xlsx'
test.get_shock_excel(path=save_path)
An excel file will be created in the given path. The excel file has 6 different pages as follow:
- indeces: this page contains all the valid data that can be used for the definition of the shocks. These values are used to validate the data on other sheets
- main: This sheet is an optional sheet that user may use for the intermediate calculations and defining the assumptions of the problem
- Y: This sheet is specified for implementing a shock on the Final demand
- v: This sheet is specified for implementing a shock on tha value added
- e: This sheet is specified for implementing a shock on the satellite account
- z: This sheet is specified for implementing a shock on the intersectoral transaction matrix
In this version of mario, there are different ways to implement a shock (more options will be added to the next versions):
- update: this method updates a value on the coefficient matrix
- Absolute: this method implements the change in terms of absolute values (flows) and implement the change on coefficient matrix
- Percentage: this method implements a percentage change directly on coefficient matrix (the values should be between 0 to 1 meaning that 10% increase is 0.1 and 10% decrease is -0.1)
For example, a scenario with 10% increase in the self consumption of services sector in Italy can be modeled in the excel file as follow:
Finally, the excel file can be passed to shock function to implement the shock
test.shock_calc(io=r'shock_iot.xlsx', # Path to the excel file
z= True, # the shock will be implemented on z
notes=['you may add some notes for metadata']
)
C:\Users\payam\anaconda3\lib\site-packages\openpyxl\worksheet\_reader.py:308: UserWarning: Data Validation extension is not supported and will be removed
# new scenario is added to the list of scenarios
print(test.scenarios)
['baseline', 'shock 1']
# the shock is recorded on metadata
test.meta_history
[14:28:52] Table added into metadata with value equal to IOT. [14:28:52] Price added into metadata with value equal to None. [14:28:52] Source added into metadata with value equal to None. [14:28:52] Year added into metadata with value equal to None. [14:28:52] Database successfully imported. [14:28:52] Number of Region = 2 [14:28:52] Number of Consumption category = 1 [14:28:52] Number of Satellite account = 4 [14:28:52] Number of Factor of production = 3 [14:28:52] Number of Sector = 6 [14:29:45] Shocks implemented from shock_iot.xlsx as follow: [14:29:45] Shock (Notes): you may add some notes for metadata [14:29:45] Shock on z implemented: row_region_:Italy, row_level_:Sector, row_sector_:Services, column_region_:Italy, column_level_:Sector column_sector_:Services, type: Percentage, value: 0.1.
Defining the Clusters¶
In order to impelemnt shocks on a bunch of items, you can use clusters. Lets implement a change in the local final demand of all sectors in italy for 10%, first without the clusters.
In this way, user needs to replicate the same change for all the sectros in italy as shown in the picture
An easier way to this shock is to use clusters. In this case user needs to define a cluster on the 'Sector'. But clusters can be defined on all the sets of the table (for checking all the sets of table you can use test.sets)
A cluster on sectors can be defined as follow:
clusters = {'Sector': # Cluster on which set
{'All': test.get_index('Sector') # what is the name of the cluster and what it contains
}
}
So in this case, we are making a cluster on Sector. The cluster will be called All and it contains all the Sectors in the database. Now if we request mario to generate the shock excel, 'All' is added as a valid option for the Sector.
save_path = r'shock_iot_cluster.xlsx'
test.get_shock_excel(path=save_path,**clusters)
The same shock now can be implemented as the shown in the pic:
In order to implement a shock, we need to use the excel files and the definition of clusters as follow:
test.shock_calc(io=r'shock_iot_cluster.xlsx', # Path to the excel file
Y= True, # the shock will be implemented on Y
**clusters
)
# lets look at the meta history
test.meta_history
[14:28:52] Table added into metadata with value equal to IOT. [14:28:52] Price added into metadata with value equal to None. [14:28:52] Source added into metadata with value equal to None. [14:28:52] Year added into metadata with value equal to None. [14:28:52] Database successfully imported. [14:28:52] Number of Region = 2 [14:28:52] Number of Consumption category = 1 [14:28:52] Number of Satellite account = 4 [14:28:52] Number of Factor of production = 3 [14:28:52] Number of Sector = 6 [14:29:45] Shocks implemented from shock_iot.xlsx as follow: [14:29:45] Shock (Notes): you may add some notes for metadata [14:29:45] Shock on z implemented: row_region_:Italy, row_level_:Sector, row_sector_:Services, column_region_:Italy, column_level_:Sector column_sector_:Services, type: Percentage, value: 0.1. [14:30:53] Shocks implemented from shock_iot_cluster.xlsx as follow: [14:30:53] Shock on Y implemented: row_region:Italy, row_level:Sector, row_sector:['Agriculture', 'Mining', 'Manufacturing', 'Services', 'Construction', 'Transport'], column_region:Italy, demand_category: Final Demand, type: Percentage, value: 0.1.
# lets have a look on the changes
test['shock 2']['Y']-test['baseline']['Y']
Region | Italy | RoW | ||
---|---|---|---|---|
Level | Consumption category | Consumption category | ||
Item | Final Demand | Final Demand | ||
Region | Level | Item | ||
Italy | Sector | Agriculture | 2843.470784 | 0.0 |
Construction | 14477.315982 | 0.0 | ||
Manufacturing | 29989.891113 | 0.0 | ||
Mining | 92.199216 | 0.0 | ||
Services | 105284.650130 | 0.0 | ||
Transport | 5738.524814 | 0.0 | ||
RoW | Sector | Agriculture | 0.000000 | 0.0 |
Construction | 0.000000 | 0.0 | ||
Manufacturing | 0.000000 | 0.0 | ||
Mining | 0.000000 | 0.0 | ||
Services | 0.000000 | 0.0 | ||
Transport | 0.000000 | 0.0 |