Shcok Analysis¶
A scenario can be implemented in multiple ways within mario.
Shock implementation using python script¶
In this approach, you need to use the pandas functions properly to implement changes in your database, and update the matrices in mario scenario accordingly. Lets load the test example to see how it works.
from mario import load_test,slicer
test = load_test("IOT")
Let’s assume you want to model a final demand increase scenario in your database. The first step would be to clone a new scneario from baseline data:
test.clone_scenario(
scenario='baseline', # from which scenario clone
name='Final demand increase',# what will be the name of the new scenario
)
print(test.scenarios)
['baseline', 'Final demand increase']
Now lets assume you want to increase the local final demand of agriculture sectors in Italy by 10%. This is how the matrix of final demand (Y) looks like:
test.Y
Region | Italy | RoW | ||
---|---|---|---|---|
Level | Consumption category | Consumption category | ||
Item | Final Demand | Final Demand | ||
Region | Level | Item | ||
Italy | Sector | Agriculture | 2.843471e+04 | 4.875449e+03 |
Construction | 1.447732e+05 | 4.655076e+02 | ||
Manufacturing | 2.998989e+05 | 2.316510e+05 | ||
Mining | 9.219922e+02 | 2.023559e+02 | ||
Services | 1.052847e+06 | 5.080214e+04 | ||
Transport | 5.738525e+04 | 5.686902e+03 | ||
RoW | Sector | Agriculture | 1.099317e+04 | 2.073065e+06 |
Construction | 1.072044e+03 | 1.059925e+07 | ||
Manufacturing | 1.217507e+05 | 1.816087e+07 | ||
Mining | 4.621724e+02 | 4.603934e+05 | ||
Services | 4.307168e+04 | 4.842609e+07 | ||
Transport | 8.726021e+03 | 3.100367e+06 |
So you need to slice the database properly to increase the total final demand of agriculture sector in Italy. For easier use, you can use mario slicer function in case you dont want to deal with slicing of pandas through loc function:
Y_rows = slicer(matrix='Y',axis= 0,Region=['Italy'],Item=['Agriculture'])
Y_cols = slicer(matrix='Y',axis= 1,Region=['Italy'],Item=['Final Demand'])
Now you can increase the specific value by 10% as:
Y_new = test.query(
matrices = "Y",
scenarios="Final demand increase"
)
Y_new.loc[Y_rows,Y_cols] *= 1.1
print("Baseline Y",test.Y.loc[Y_rows,Y_cols])
print("Scenario Y",Y_new.loc[Y_rows,Y_cols])
Baseline Y Region Italy
Level Consumption category
Item Final Demand
Region Level Item
Italy Sector Agriculture 28434.707841
Scenario Y Region Italy
Level Consumption category
Item Final Demand
Region Level Item
Italy Sector Agriculture 31278.178625
Now you need to update the scenario data then reset all the matrices of scenario to coefficients only (as they are not changed!), to recaulcuate the matrices again.
test.update_scenarios(scenario='Final demand increase',Y=Y_new)
test.reset_to_coefficients(scenario='Final demand increase')
Lets take a look to a graph to see how things look like:
# Change in total production
delta_X = test.query(
matrices = "X", # which matrix
scenarios = "Final demand increase", # take the new scenario
base_scenario="baseline", # take the base scenario
type = "absolute" # calcualte the absolute changes
)
delta_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 |
delta_X.plot(kind="bar")
<Axes: xlabel='Region,Level,Item'>

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.
Lets implement a different shock, by first loading a fresh test example.
test = load_test("IOT")
You can ask mario to generate an excel file where you can fill your shocks!
save_path = "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:

Alt text¶
Let’s assume that we fill the excel file, and call it shock_iot_filled.xlsx. To implement the shock, you can:
test.shock_calc(
io=r'shock_iot_filled.xlsx', # Path to the excel file
z= True, # the shock will be implemented on z
notes=['you may add some notes for metadata']
)
test.scenarios
['baseline', 'shock 1']
If you dont choose a name for your shock, mario will do it for you!
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

Alt text¶
n 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 = '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:

Alt text¶
In order to implement a shock, we need to use the excel files and the definition of clusters as follow. Let’s assume we call the filled excel file as shock_iot_cluster_filled.xlsx:
test.shock_calc(
io=r'shock_iot_cluster_filled.xlsx', # Path to the excel file
Y= True, # the shock will be implemented on Y
**clusters
)
test.scenarios
['baseline', 'shock 1', 'shock 2']
Just to understand what is happening behind the scene, you can take a look to the metadata history:
test.meta_history
[2024-06-26 18:54:48] Table added into metadata with value equal to IOT.
[2024-06-26 18:54:48] Price added into metadata with value equal to None.
[2024-06-26 18:54:48] Source added into metadata with value equal to None.
[2024-06-26 18:54:48] Year added into metadata with value equal to None.
[2024-06-26 18:54:48] Shocks implemented from shock_iot_filled.xlsx as follow:
[2024-06-26 18:54:48] Shock (Notes): you may add some notes for metadata
[2024-06-26 18:54:48] 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.
[2024-06-26 18:54:48] Shocks implemented from shock_iot_cluster_filled.xlsx as follow:
[2024-06-26 18:54:48] 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.
Link to the jupyter notebook file
.