iotables 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- iotables/__init__.py +43 -0
- iotables/base_io.py +339 -0
- iotables/config.py +195 -0
- iotables/exiobase.py +194 -0
- iotables/figaro.py +163 -0
- iotables/globals.py +10 -0
- iotables/mappings.py +409 -0
- iotables/matrix.py +84 -0
- iotables/oecd.py +181 -0
- iotables/py.typed +0 -0
- iotables/utils.py +156 -0
- iotables-0.1.0.dist-info/METADATA +311 -0
- iotables-0.1.0.dist-info/RECORD +16 -0
- iotables-0.1.0.dist-info/WHEEL +5 -0
- iotables-0.1.0.dist-info/licenses/LICENSE +7 -0
- iotables-0.1.0.dist-info/top_level.txt +1 -0
iotables/__init__.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import os as _os
|
|
2
|
+
from importlib.metadata import version as _version, PackageNotFoundError as _PackageNotFoundError
|
|
3
|
+
from iotables.globals import DATA_FOLDER as __DATA_FOLDER
|
|
4
|
+
from iotables.globals import IS_WINDOWS as __IS_WINDOWS
|
|
5
|
+
from iotables.globals import FILES_LOG as __FILES_LOG
|
|
6
|
+
from iotables.oecd import OECD
|
|
7
|
+
from iotables.figaro import Figaro
|
|
8
|
+
from iotables.exiobase import ExioBase
|
|
9
|
+
from iotables.utils import remove_downloaded_files
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
__version__ = _version("iotables")
|
|
13
|
+
except _PackageNotFoundError: # package not installed (e.g. running from source tree)
|
|
14
|
+
__version__ = "0.0.0"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_size_data_folder():
|
|
18
|
+
"""Get size of the folder where downloaded files are stored
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
str: Size of folder
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
def get_size(folder):
|
|
27
|
+
def human(size):
|
|
28
|
+
UNITS = ["B", "KB", "MB", "GB", "TB"]
|
|
29
|
+
HUMANFMT = "{size} {unit}"
|
|
30
|
+
HUMANRADIX = 1024.
|
|
31
|
+
for u in UNITS[:-1]:
|
|
32
|
+
if size < HUMANRADIX:
|
|
33
|
+
return HUMANFMT.format(size=round(size, 2), unit=u)
|
|
34
|
+
size /= HUMANRADIX
|
|
35
|
+
return HUMANFMT.format(size=round(size, 2), unit=UNITS[-1])
|
|
36
|
+
|
|
37
|
+
root_directory = Path(folder)
|
|
38
|
+
tot_size = sum(f.stat().st_size for f in root_directory.glob('**/*') if f.is_file())
|
|
39
|
+
return human(tot_size)
|
|
40
|
+
return get_size(__DATA_FOLDER)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
_os.makedirs(__DATA_FOLDER, exist_ok=True)
|
iotables/base_io.py
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
"""Shared analysis engine: derives the coefficient/inverse matrices and runs shocks."""
|
|
2
|
+
from warnings import warn
|
|
3
|
+
from iotables.matrix import Matrix
|
|
4
|
+
from iotables.utils import assert_is_subset
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
from typing import Union, Iterable, Optional
|
|
7
|
+
import numpy as np
|
|
8
|
+
import pandas as pd
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class IO:
|
|
12
|
+
"""Class for creating standard IO matrices and IO helper functions, meant as a parent
|
|
13
|
+
class for classes that load IO data.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self):
|
|
17
|
+
necessary_attrs = ['Z',
|
|
18
|
+
'X',
|
|
19
|
+
'V',
|
|
20
|
+
'FD',
|
|
21
|
+
'FD_GRAN',
|
|
22
|
+
'ADD',
|
|
23
|
+
'FD_REGION',
|
|
24
|
+
'rs',
|
|
25
|
+
'sector_name_mapping',
|
|
26
|
+
'regions',
|
|
27
|
+
'sectors',
|
|
28
|
+
'unit',
|
|
29
|
+
'demand_items',
|
|
30
|
+
'reference',
|
|
31
|
+
'contact']
|
|
32
|
+
assert_is_subset(necessary_attrs, dir(self))
|
|
33
|
+
|
|
34
|
+
# Coefficients matrix, replace 0 with 1 to allow inversion
|
|
35
|
+
x_filled = self.X.copy()
|
|
36
|
+
x_filled[x_filled == 0] = 1
|
|
37
|
+
|
|
38
|
+
# Leontief demand side
|
|
39
|
+
self.A = Matrix('Technical coefficients',
|
|
40
|
+
self.Z / x_filled.flatten(),
|
|
41
|
+
self.Z.rows,
|
|
42
|
+
self.Z.columns)
|
|
43
|
+
|
|
44
|
+
self.L = Matrix('Leontief inverse',
|
|
45
|
+
(np.eye(self.rs) - self.A).I,
|
|
46
|
+
self.Z.rows,
|
|
47
|
+
self.Z.columns)
|
|
48
|
+
|
|
49
|
+
# Ghosh supply side
|
|
50
|
+
self.B = Matrix('Allocation coefficients',
|
|
51
|
+
self.Z / x_filled,
|
|
52
|
+
self.Z.rows,
|
|
53
|
+
self.Z.columns)
|
|
54
|
+
|
|
55
|
+
self.G = Matrix('Ghosh inverse',
|
|
56
|
+
(np.eye(self.rs) - self.B).I,
|
|
57
|
+
self.Z.rows,
|
|
58
|
+
self.Z.columns)
|
|
59
|
+
|
|
60
|
+
def _shock(self,
|
|
61
|
+
model: str,
|
|
62
|
+
shock: Union[int, float, None] = None,
|
|
63
|
+
regions: Optional[Iterable] = None,
|
|
64
|
+
sectors: Optional[Iterable] = None,
|
|
65
|
+
custom_shock_vector: Optional[Iterable] = None):
|
|
66
|
+
"""Calculates new output using Leontief or Ghosh model
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
model: leontief or ghosh
|
|
70
|
+
shock: Shock in percentage of original final demand or primary inputs
|
|
71
|
+
regions: List of regions to be shocked
|
|
72
|
+
sectors: List of sectors to be shocked
|
|
73
|
+
custom_shock_vector: Vector of length regions * sectors with percentage shocks, overrides all other shock
|
|
74
|
+
parameters if supplied
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Matrix: Shocked output
|
|
78
|
+
"""
|
|
79
|
+
if custom_shock_vector is not None:
|
|
80
|
+
shock_vector = np.array(custom_shock_vector).reshape(self.rs, 1)
|
|
81
|
+
else:
|
|
82
|
+
if shock is None or regions is None or sectors is None:
|
|
83
|
+
raise ValueError("Must supply parameters: 'shock', 'regions', 'sectors'")
|
|
84
|
+
|
|
85
|
+
assert_is_subset(regions, self.regions)
|
|
86
|
+
assert_is_subset(sectors, self.sectors)
|
|
87
|
+
|
|
88
|
+
shock_vector = np.array([shock if r in regions and s in sectors
|
|
89
|
+
else 0 for r, s in self.X.rows]).reshape(-1, 1)
|
|
90
|
+
shock_vector = shock_vector.astype('float64')
|
|
91
|
+
shock_vector /= 100
|
|
92
|
+
if model == 'leontief':
|
|
93
|
+
x_new = (self.L @ (self.FD * shock_vector)) + self.X
|
|
94
|
+
elif model == 'ghosh':
|
|
95
|
+
x_new = (self.G.T @ (self.V.T * shock_vector)) + self.X
|
|
96
|
+
else:
|
|
97
|
+
raise ValueError('model must be leontief or ghosh')
|
|
98
|
+
|
|
99
|
+
return x_new
|
|
100
|
+
|
|
101
|
+
def _shock_to_df(self,
|
|
102
|
+
x_new: Matrix):
|
|
103
|
+
"""Creates a pandas dataframe with columns: region, sector, x and x_new
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
x_new: New output
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
pd.DataFrame
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
return pd.DataFrame({'region': [r for r, s in self.X.rows],
|
|
113
|
+
'sector': [s for r, s in self.X.rows],
|
|
114
|
+
'x': self.X.flatten(),
|
|
115
|
+
'x_new': x_new.flatten()})
|
|
116
|
+
|
|
117
|
+
def _shock_and_plot(self,
|
|
118
|
+
model: str,
|
|
119
|
+
shock: Union[int, float, None] = None,
|
|
120
|
+
regions: Optional[Iterable] = None,
|
|
121
|
+
sectors: Optional[Iterable] = None,
|
|
122
|
+
custom_shock_vector: Optional[Iterable] = None,
|
|
123
|
+
plot: bool = False,
|
|
124
|
+
plot_by: str = 'region',
|
|
125
|
+
plot_regions: Optional[Iterable] = None,
|
|
126
|
+
show: bool = True,
|
|
127
|
+
):
|
|
128
|
+
"""Executes a Leontief demand or Ghosh supply shock
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
model: leontief or ghosh
|
|
132
|
+
shock: Shock in percentage of original final demand or primary inputs
|
|
133
|
+
regions: List of regions to be shocked
|
|
134
|
+
sectors: List of sectors to be shocked
|
|
135
|
+
custom_shock_vector: Vector of length regions * sectors with percentage shocks, overrides all other shock
|
|
136
|
+
parameters if supplied
|
|
137
|
+
plot: Plot if true
|
|
138
|
+
plot_by: region or sector; if sector, the top 20 is shown
|
|
139
|
+
plot_regions: List of regions to plot the effect for
|
|
140
|
+
show: Show the plot if true
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
pd.DataFrame: df with shocked output vector if plot is False, else matplotlib fig, ax
|
|
144
|
+
"""
|
|
145
|
+
x_new = self._shock(model=model, shock=shock, regions=regions, sectors=sectors,
|
|
146
|
+
custom_shock_vector=custom_shock_vector)
|
|
147
|
+
|
|
148
|
+
if plot:
|
|
149
|
+
if plot_regions is None:
|
|
150
|
+
raise ValueError("Please specify 'plot_regions'")
|
|
151
|
+
fig, ax = self._plot_shock(x_new=x_new, model=model, by=plot_by, regions=plot_regions)
|
|
152
|
+
if show:
|
|
153
|
+
plt.show()
|
|
154
|
+
return fig, ax
|
|
155
|
+
|
|
156
|
+
return self._shock_to_df(x_new)
|
|
157
|
+
|
|
158
|
+
def _plot_shock(self,
|
|
159
|
+
x_new: Matrix,
|
|
160
|
+
model: str,
|
|
161
|
+
by: str,
|
|
162
|
+
regions: Iterable):
|
|
163
|
+
"""Plot shock from a given new output
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
x_new: New output
|
|
167
|
+
model: ghosh or leontief
|
|
168
|
+
by: region or sector
|
|
169
|
+
regions: List of regions to plot the effect for
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
fig, ax
|
|
173
|
+
"""
|
|
174
|
+
if by not in {'region', 'sector'}:
|
|
175
|
+
raise ValueError("plot_by must be 'region' or 'sector'")
|
|
176
|
+
assert_is_subset(regions, self.regions)
|
|
177
|
+
|
|
178
|
+
df = self._shock_to_df(x_new)
|
|
179
|
+
df['diff'] = (df.x_new / df.x - 1).fillna(0)
|
|
180
|
+
df['col'] = self.V.flatten() if model == 'leontief' else self.FD.flatten()
|
|
181
|
+
df['newcol'] = df['col'] * (1 + df['diff'])
|
|
182
|
+
|
|
183
|
+
df = df[df.region.isin(regions)].groupby(by)[['col', 'newcol']].sum(0)
|
|
184
|
+
if by == 'sector':
|
|
185
|
+
df.index = df.index.map(self.sector_name_mapping).str[:25]
|
|
186
|
+
df['diff'] = (100 * (df.newcol / df.col - 1)).fillna(0)
|
|
187
|
+
df.sort_values('diff', inplace=True, ascending=False)
|
|
188
|
+
if by == 'sector':
|
|
189
|
+
if df['diff'].mean() < 0:
|
|
190
|
+
df = df.tail(20)
|
|
191
|
+
else:
|
|
192
|
+
df = df.head(20)
|
|
193
|
+
|
|
194
|
+
fig, ax = plt.subplots()
|
|
195
|
+
ax.barh(df.index,
|
|
196
|
+
df['diff']
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
if df['diff'].mean() < 0:
|
|
200
|
+
ax.invert_xaxis()
|
|
201
|
+
else:
|
|
202
|
+
ax.invert_yaxis()
|
|
203
|
+
|
|
204
|
+
plt.xlabel(f"% change in {'GVA' if model == 'leontief' else 'final demand'}")
|
|
205
|
+
|
|
206
|
+
plt.tight_layout()
|
|
207
|
+
|
|
208
|
+
return fig, ax
|
|
209
|
+
|
|
210
|
+
def leontief_demand_shock(self,
|
|
211
|
+
shock: Union[int, float, None] = None,
|
|
212
|
+
regions: Optional[Iterable] = None,
|
|
213
|
+
sectors: Optional[Iterable] = None,
|
|
214
|
+
custom_shock_vector: Optional[Iterable] = None,
|
|
215
|
+
plot: bool = False,
|
|
216
|
+
plot_by: str = 'region',
|
|
217
|
+
plot_regions: Optional[Iterable] = None,
|
|
218
|
+
show: bool = True,
|
|
219
|
+
):
|
|
220
|
+
"""Executes a Leontief demand shock
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
shock: Shock in percentage of original demand
|
|
224
|
+
regions: List of regions to be shocked
|
|
225
|
+
sectors: List of sectors to be shocked
|
|
226
|
+
custom_shock_vector: Vector of length regions * sectors with percentage shocks, overrides all other shock
|
|
227
|
+
parameters if supplied
|
|
228
|
+
plot: Plot if true
|
|
229
|
+
plot_by: region or sector; if sector, the top 20 is shown
|
|
230
|
+
plot_regions: List of regions to plot the effect for
|
|
231
|
+
show: Show the plot if true
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
pd.DataFrame: df with shocked output vector if plot is False, else matplotlib fig, ax
|
|
235
|
+
"""
|
|
236
|
+
return self._shock_and_plot(model='leontief',
|
|
237
|
+
shock=shock,
|
|
238
|
+
regions=regions,
|
|
239
|
+
sectors=sectors,
|
|
240
|
+
custom_shock_vector=custom_shock_vector,
|
|
241
|
+
plot=plot,
|
|
242
|
+
plot_by=plot_by,
|
|
243
|
+
plot_regions=plot_regions,
|
|
244
|
+
show=show)
|
|
245
|
+
|
|
246
|
+
def ghosh_supply_shock(self,
|
|
247
|
+
shock: Union[int, float, None] = None,
|
|
248
|
+
regions: Optional[Iterable] = None,
|
|
249
|
+
sectors: Optional[Iterable] = None,
|
|
250
|
+
custom_shock_vector: Optional[Iterable] = None,
|
|
251
|
+
plot: bool = False,
|
|
252
|
+
plot_by: str = 'region',
|
|
253
|
+
plot_regions: Optional[Iterable] = None,
|
|
254
|
+
show: bool = True,
|
|
255
|
+
):
|
|
256
|
+
"""Executes a Ghosh supply shock
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
shock: Shock in percentage of original primary inputs (value added)
|
|
260
|
+
regions: List of regions to be shocked
|
|
261
|
+
sectors: List of sectors to be shocked
|
|
262
|
+
custom_shock_vector: Vector of length regions * sectors with percentage shocks, overrides all other shock
|
|
263
|
+
parameters if supplied
|
|
264
|
+
plot: Plot if true
|
|
265
|
+
plot_by: region or sector; if sector, the top 20 is shown
|
|
266
|
+
plot_regions: List of regions to plot the effect for
|
|
267
|
+
show: Show the plot if true
|
|
268
|
+
|
|
269
|
+
Returns:
|
|
270
|
+
pd.DataFrame: df with shocked output vector if plot is False, else matplotlib fig, ax
|
|
271
|
+
"""
|
|
272
|
+
return self._shock_and_plot(model='ghosh',
|
|
273
|
+
shock=shock,
|
|
274
|
+
regions=regions,
|
|
275
|
+
sectors=sectors,
|
|
276
|
+
custom_shock_vector=custom_shock_vector,
|
|
277
|
+
plot=plot,
|
|
278
|
+
plot_by=plot_by,
|
|
279
|
+
plot_regions=plot_regions,
|
|
280
|
+
show=show)
|
|
281
|
+
|
|
282
|
+
def get_imports_exports(self,
|
|
283
|
+
import_regions: Iterable,
|
|
284
|
+
export_regions: Iterable,
|
|
285
|
+
import_sectors: Optional[Iterable] = None,
|
|
286
|
+
export_sectors: Optional[Iterable] = None,
|
|
287
|
+
use_type: str = 'both'):
|
|
288
|
+
"""Get imports and exports between regions and sectors. Use is broken down by intermediate use and final demand,
|
|
289
|
+
specify 'use_type' to get either of them or both summed together.
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
import_regions: List of importing regions
|
|
293
|
+
export_regions: List of exporting regions
|
|
294
|
+
import_sectors: List of importing sectors, all sectors by default, only accounts for intermediate import sectors
|
|
295
|
+
export_sectors: List of exporting sectors, all sectors by default
|
|
296
|
+
use_type: 'intermediate', 'final', or 'both'
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
float: Sum of trade flow from exporting region-sectors to importing region-sectors
|
|
300
|
+
"""
|
|
301
|
+
if use_type not in {'intermediate', 'final', 'both'}:
|
|
302
|
+
raise ValueError("use_type must be 'intermediate', 'final' or 'both'")
|
|
303
|
+
|
|
304
|
+
if import_sectors is not None and use_type in {'final', 'both'}:
|
|
305
|
+
warn('Note that import_sectors only apply to intermediate use, for final use only import_regions is used')
|
|
306
|
+
|
|
307
|
+
if import_sectors is None:
|
|
308
|
+
import_sectors = self.sectors
|
|
309
|
+
if export_sectors is None:
|
|
310
|
+
export_sectors = self.sectors
|
|
311
|
+
|
|
312
|
+
if isinstance(import_regions, str):
|
|
313
|
+
import_regions = [import_regions]
|
|
314
|
+
if isinstance(export_regions, str):
|
|
315
|
+
export_regions = [export_regions]
|
|
316
|
+
if isinstance(import_sectors, str):
|
|
317
|
+
import_sectors = [import_sectors]
|
|
318
|
+
if isinstance(export_sectors, str):
|
|
319
|
+
export_sectors = [export_sectors]
|
|
320
|
+
|
|
321
|
+
for subset, superset in zip([import_regions, export_regions, import_sectors, export_sectors],
|
|
322
|
+
[self.regions, self.regions, self.sectors, self.sectors]):
|
|
323
|
+
assert_is_subset(subset, superset)
|
|
324
|
+
|
|
325
|
+
if set(import_regions).intersection(export_regions):
|
|
326
|
+
warn(f'There is overlap between import_regions and export_regions: '
|
|
327
|
+
f'{", ".join(set(import_regions).intersection(export_regions))}')
|
|
328
|
+
|
|
329
|
+
intermediate = float(self.Z[np.ix_([r in export_regions and s in export_sectors for r, s in self.Z.rows],
|
|
330
|
+
[r in import_regions and s in import_sectors for r, s in
|
|
331
|
+
self.Z.columns])].sum())
|
|
332
|
+
|
|
333
|
+
final = float(
|
|
334
|
+
self.FD_REGION[np.ix_([r in export_regions and s in export_sectors for r, s in self.FD_REGION.rows],
|
|
335
|
+
[r in import_regions for r in self.FD_REGION.columns])].sum())
|
|
336
|
+
|
|
337
|
+
return {'intermediate': intermediate,
|
|
338
|
+
'final': final,
|
|
339
|
+
'both': intermediate + final}[use_type]
|
iotables/config.py
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"""Single source of truth for the data that exists: download links and shapes per database."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def _chunk_links(base, chunks):
|
|
5
|
+
"""Expand ``{filename: (start_year, end_year)}`` into ``{year: url}``.
|
|
6
|
+
|
|
7
|
+
OECD distributes each ICIO edition as a handful of multi-year zip archives
|
|
8
|
+
(e.g. ``2016-2022_SML.zip`` holds one CSV per year), so every year in a range
|
|
9
|
+
resolves to the same download URL.
|
|
10
|
+
"""
|
|
11
|
+
return {year: base + filename
|
|
12
|
+
for filename, (start, end) in chunks.items()
|
|
13
|
+
for year in range(start, end + 1)}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _circabc_links(kind_tag, ids):
|
|
17
|
+
"""Build CIRCABC anonymous download URLs for Figaro from ``{year: node_id}``.
|
|
18
|
+
|
|
19
|
+
Eurostat distributes the Figaro 2025 edition through CIRCABC; every file has a
|
|
20
|
+
stable, auth-free download URL of the form ``/sd/a/{node_id}/{filename}``.
|
|
21
|
+
"""
|
|
22
|
+
return {year: f'https://circabc.europa.eu/sd/a/{nid}/matrix_eu-ic-io_{kind_tag}_25ed_{year}.csv'
|
|
23
|
+
for year, nid in ids.items()}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
config = {
|
|
27
|
+
'oecd':
|
|
28
|
+
{'2021':
|
|
29
|
+
{'links': _chunk_links('https://webfs-sti.oecd.org/files/STI-PIE/ICIO/2021/', {
|
|
30
|
+
'ICIO2021_1995-1999.zip': (1995, 1999),
|
|
31
|
+
'ICIO2021_2000-2004.zip': (2000, 2004),
|
|
32
|
+
'ICIO2021_2005-2009.zip': (2005, 2009),
|
|
33
|
+
'ICIO2021_2010-2014.zip': (2010, 2014),
|
|
34
|
+
'ICIO2021_2015-2018.zip': (2015, 2018),
|
|
35
|
+
}),
|
|
36
|
+
'regex_id': r'ICIO2021_[0-9]{4}-[0-9]{4}',
|
|
37
|
+
'num_regions': 71,
|
|
38
|
+
'num_sectors': 45
|
|
39
|
+
},
|
|
40
|
+
'2022-extended':
|
|
41
|
+
{'links': _chunk_links('https://webfs-sti.oecd.org/files/STI-PIE/ICIO/2023/', {
|
|
42
|
+
'1995-2000_EXT.zip': (1995, 2000),
|
|
43
|
+
'2001-2005_EXT.zip': (2001, 2005),
|
|
44
|
+
'2006-2010_EXT.zip': (2006, 2010),
|
|
45
|
+
'2011-2015_EXT.zip': (2011, 2015),
|
|
46
|
+
'2016-2020_EXT.zip': (2016, 2020),
|
|
47
|
+
}),
|
|
48
|
+
'regex_id': r'2023/[0-9]{4}-[0-9]{4}_EXT',
|
|
49
|
+
'num_regions': 81,
|
|
50
|
+
'num_sectors': 45},
|
|
51
|
+
'2022-small':
|
|
52
|
+
{'links': _chunk_links('https://webfs-sti.oecd.org/files/STI-PIE/ICIO/2023/', {
|
|
53
|
+
'1995-2000_SML.zip': (1995, 2000),
|
|
54
|
+
'2001-2005_SML.zip': (2001, 2005),
|
|
55
|
+
'2006-2010_SML.zip': (2006, 2010),
|
|
56
|
+
'2011-2015_SML.zip': (2011, 2015),
|
|
57
|
+
'2016-2020_SML.zip': (2016, 2020),
|
|
58
|
+
}),
|
|
59
|
+
'regex_id': r'2023/[0-9]{4}-[0-9]{4}_SML',
|
|
60
|
+
'num_regions': 77,
|
|
61
|
+
'num_sectors': 45},
|
|
62
|
+
'2025-extended':
|
|
63
|
+
{'links': _chunk_links('https://webfs-sti.oecd.org/files/STI-PIE/ICIO/2025/', {
|
|
64
|
+
'1995-2000_EXT.zip': (1995, 2000),
|
|
65
|
+
'2001-2005_EXT.zip': (2001, 2005),
|
|
66
|
+
'2006-2010_EXT.zip': (2006, 2010),
|
|
67
|
+
'2011-2015_EXT.zip': (2011, 2015),
|
|
68
|
+
'2016-2022_EXT.zip': (2016, 2022),
|
|
69
|
+
}),
|
|
70
|
+
'regex_id': r'2025/[0-9]{4}-[0-9]{4}_EXT',
|
|
71
|
+
'num_regions': 85,
|
|
72
|
+
'num_sectors': 50},
|
|
73
|
+
'2025-regular':
|
|
74
|
+
{'links': _chunk_links('https://webfs-sti.oecd.org/files/STI-PIE/ICIO/2025/', {
|
|
75
|
+
'1995-2000_SML.zip': (1995, 2000),
|
|
76
|
+
'2001-2005_SML.zip': (2001, 2005),
|
|
77
|
+
'2006-2010_SML.zip': (2006, 2010),
|
|
78
|
+
'2011-2015_SML.zip': (2011, 2015),
|
|
79
|
+
'2016-2022_SML.zip': (2016, 2022),
|
|
80
|
+
}),
|
|
81
|
+
'regex_id': r'2025/[0-9]{4}-[0-9]{4}_SML',
|
|
82
|
+
'num_regions': 81,
|
|
83
|
+
'num_sectors': 50}
|
|
84
|
+
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
'figaro':
|
|
88
|
+
{
|
|
89
|
+
'2025':
|
|
90
|
+
{'links':
|
|
91
|
+
{'product-by-product': _circabc_links('prod-by-prod', {
|
|
92
|
+
2010: 'f6d2007e-34c9-420a-a106-8c5ea836c49d',
|
|
93
|
+
2011: 'd27f7d7c-4006-4c36-8820-7d9990679323',
|
|
94
|
+
2012: '7cea8b73-f166-47ff-9c27-f240794b57af',
|
|
95
|
+
2013: 'd56c2ed9-0c4f-40a3-9bbc-1aee49f5bd45',
|
|
96
|
+
2014: 'b5aa0e38-3d1b-496b-b180-bbd9bab3e153',
|
|
97
|
+
2015: 'd037b772-8bf9-424f-97a4-9274d261e6cf',
|
|
98
|
+
2016: '66369d21-8262-47d6-ad8a-dc536a2466d0',
|
|
99
|
+
2017: 'd6848c38-9569-4848-bb68-4144fed38c71',
|
|
100
|
+
2018: '557b9483-023e-497c-96c5-44ce807bd444',
|
|
101
|
+
2019: 'fa0e9127-7a2b-4b74-bbad-1bc9e717197b',
|
|
102
|
+
2020: '46f5665e-d2e1-4270-95a1-970da3d70d32',
|
|
103
|
+
2021: 'a7e2919d-f084-4c35-8b21-e960a854e2bd',
|
|
104
|
+
2022: '31484cee-43fe-45d4-a546-209e5898c6dd',
|
|
105
|
+
2023: 'e213892a-afac-4d34-83e9-45e8a324e7e8',
|
|
106
|
+
}),
|
|
107
|
+
'industry-by-industry': _circabc_links('ind-by-ind', {
|
|
108
|
+
2010: 'fc80f855-d144-476e-b4bf-5cfba946819c',
|
|
109
|
+
2011: '1bcb2624-04ed-43e1-8588-df6680ed352a',
|
|
110
|
+
2012: '399671ad-cbb3-493e-ad5f-83e989f1eecc',
|
|
111
|
+
2013: 'a2b4746d-1d11-4a44-ab1c-50ac956f0849',
|
|
112
|
+
2014: 'beba57b2-2696-497a-b92f-2a5beca724c7',
|
|
113
|
+
2015: '1a194b8c-6ea1-4bec-9c73-0cd599febcc3',
|
|
114
|
+
2016: '2cdd74fc-0bce-4ae0-8bf2-34d34546d86d',
|
|
115
|
+
2017: '4a11c796-4186-4cce-a02f-12d353fc5e59',
|
|
116
|
+
2018: '7a57a374-2200-498c-bb5f-cee24202b0b8',
|
|
117
|
+
2019: 'c3467617-8a00-44a0-9b6b-ccad8a2ab58d',
|
|
118
|
+
2020: '4df668e1-2a8a-4e84-ae57-00309d8bc760',
|
|
119
|
+
2021: '6736dea8-da14-450f-b212-a791baf238c8',
|
|
120
|
+
2022: 'b20c339d-984f-413c-a499-54ff76beb90c',
|
|
121
|
+
2023: '21557f49-1e94-431c-8523-d972fec020b8',
|
|
122
|
+
})},
|
|
123
|
+
'regex_id': r'matrix_eu-ic-io_[a-z-]+_25ed_[0-9]{4}',
|
|
124
|
+
'num_regions': 50,
|
|
125
|
+
'num_sectors': 64},
|
|
126
|
+
},
|
|
127
|
+
'exiobase':
|
|
128
|
+
{'3.81':
|
|
129
|
+
{'links':
|
|
130
|
+
{'product-by-product': {
|
|
131
|
+
1995: 'https://zenodo.org/record/5589597/files/IOT_1995_pxp.zip?download=1',
|
|
132
|
+
1996: 'https://zenodo.org/record/5589597/files/IOT_1996_pxp.zip?download=1',
|
|
133
|
+
1997: 'https://zenodo.org/record/5589597/files/IOT_1997_pxp.zip?download=1',
|
|
134
|
+
1998: 'https://zenodo.org/record/5589597/files/IOT_1998_pxp.zip?download=1',
|
|
135
|
+
1999: 'https://zenodo.org/record/5589597/files/IOT_1999_pxp.zip?download=1',
|
|
136
|
+
2000: 'https://zenodo.org/record/5589597/files/IOT_2000_pxp.zip?download=1',
|
|
137
|
+
2001: 'https://zenodo.org/record/5589597/files/IOT_2001_pxp.zip?download=1',
|
|
138
|
+
2002: 'https://zenodo.org/record/5589597/files/IOT_2002_pxp.zip?download=1',
|
|
139
|
+
2003: 'https://zenodo.org/record/5589597/files/IOT_2003_pxp.zip?download=1',
|
|
140
|
+
2004: 'https://zenodo.org/record/5589597/files/IOT_2004_pxp.zip?download=1',
|
|
141
|
+
2005: 'https://zenodo.org/record/5589597/files/IOT_2005_pxp.zip?download=1',
|
|
142
|
+
2006: 'https://zenodo.org/record/5589597/files/IOT_2006_pxp.zip?download=1',
|
|
143
|
+
2007: 'https://zenodo.org/record/5589597/files/IOT_2007_pxp.zip?download=1',
|
|
144
|
+
2008: 'https://zenodo.org/record/5589597/files/IOT_2008_pxp.zip?download=1',
|
|
145
|
+
2009: 'https://zenodo.org/record/5589597/files/IOT_2009_pxp.zip?download=1',
|
|
146
|
+
2010: 'https://zenodo.org/record/5589597/files/IOT_2010_pxp.zip?download=1',
|
|
147
|
+
2011: 'https://zenodo.org/record/5589597/files/IOT_2011_pxp.zip?download=1',
|
|
148
|
+
2012: 'https://zenodo.org/record/5589597/files/IOT_2012_pxp.zip?download=1',
|
|
149
|
+
2013: 'https://zenodo.org/record/5589597/files/IOT_2013_pxp.zip?download=1',
|
|
150
|
+
2014: 'https://zenodo.org/record/5589597/files/IOT_2014_pxp.zip?download=1',
|
|
151
|
+
2015: 'https://zenodo.org/record/5589597/files/IOT_2015_pxp.zip?download=1',
|
|
152
|
+
2016: 'https://zenodo.org/record/5589597/files/IOT_2016_pxp.zip?download=1',
|
|
153
|
+
2017: 'https://zenodo.org/record/5589597/files/IOT_2017_pxp.zip?download=1',
|
|
154
|
+
2018: 'https://zenodo.org/record/5589597/files/IOT_2018_pxp.zip?download=1',
|
|
155
|
+
2019: 'https://zenodo.org/record/5589597/files/IOT_2019_pxp.zip?download=1',
|
|
156
|
+
2020: 'https://zenodo.org/record/5589597/files/IOT_2020_pxp.zip?download=1',
|
|
157
|
+
2021: 'https://zenodo.org/record/5589597/files/IOT_2021_pxp.zip?download=1',
|
|
158
|
+
2022: 'https://zenodo.org/record/5589597/files/IOT_2022_pxp.zip?download=1',
|
|
159
|
+
},
|
|
160
|
+
'industry-by-industry': {
|
|
161
|
+
1995: 'https://zenodo.org/record/5589597/files/IOT_1995_ixi.zip?download=1',
|
|
162
|
+
1996: 'https://zenodo.org/record/5589597/files/IOT_1996_ixi.zip?download=1',
|
|
163
|
+
1997: 'https://zenodo.org/record/5589597/files/IOT_1997_ixi.zip?download=1',
|
|
164
|
+
1998: 'https://zenodo.org/record/5589597/files/IOT_1998_ixi.zip?download=1',
|
|
165
|
+
1999: 'https://zenodo.org/record/5589597/files/IOT_1999_ixi.zip?download=1',
|
|
166
|
+
2000: 'https://zenodo.org/record/5589597/files/IOT_2000_ixi.zip?download=1',
|
|
167
|
+
2001: 'https://zenodo.org/record/5589597/files/IOT_2001_ixi.zip?download=1',
|
|
168
|
+
2002: 'https://zenodo.org/record/5589597/files/IOT_2002_ixi.zip?download=1',
|
|
169
|
+
2003: 'https://zenodo.org/record/5589597/files/IOT_2003_ixi.zip?download=1',
|
|
170
|
+
2004: 'https://zenodo.org/record/5589597/files/IOT_2004_ixi.zip?download=1',
|
|
171
|
+
2005: 'https://zenodo.org/record/5589597/files/IOT_2005_ixi.zip?download=1',
|
|
172
|
+
2006: 'https://zenodo.org/record/5589597/files/IOT_2006_ixi.zip?download=1',
|
|
173
|
+
2007: 'https://zenodo.org/record/5589597/files/IOT_2007_ixi.zip?download=1',
|
|
174
|
+
2008: 'https://zenodo.org/record/5589597/files/IOT_2008_ixi.zip?download=1',
|
|
175
|
+
2009: 'https://zenodo.org/record/5589597/files/IOT_2009_ixi.zip?download=1',
|
|
176
|
+
2010: 'https://zenodo.org/record/5589597/files/IOT_2010_ixi.zip?download=1',
|
|
177
|
+
2011: 'https://zenodo.org/record/5589597/files/IOT_2011_ixi.zip?download=1',
|
|
178
|
+
2012: 'https://zenodo.org/record/5589597/files/IOT_2012_ixi.zip?download=1',
|
|
179
|
+
2013: 'https://zenodo.org/record/5589597/files/IOT_2013_ixi.zip?download=1',
|
|
180
|
+
2014: 'https://zenodo.org/record/5589597/files/IOT_2014_ixi.zip?download=1',
|
|
181
|
+
2015: 'https://zenodo.org/record/5589597/files/IOT_2015_ixi.zip?download=1',
|
|
182
|
+
2016: 'https://zenodo.org/record/5589597/files/IOT_2016_ixi.zip?download=1',
|
|
183
|
+
2017: 'https://zenodo.org/record/5589597/files/IOT_2017_ixi.zip?download=1',
|
|
184
|
+
2018: 'https://zenodo.org/record/5589597/files/IOT_2018_ixi.zip?download=1',
|
|
185
|
+
2019: 'https://zenodo.org/record/5589597/files/IOT_2019_ixi.zip?download=1',
|
|
186
|
+
2020: 'https://zenodo.org/record/5589597/files/IOT_2020_ixi.zip?download=1',
|
|
187
|
+
2021: 'https://zenodo.org/record/5589597/files/IOT_2021_ixi.zip?download=1',
|
|
188
|
+
2022: 'https://zenodo.org/record/5589597/files/IOT_2022_ixi.zip?download=1',
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
'regex_id': r'[A-Z]{3}_[0-9]{4}_[a-z]{3}',
|
|
192
|
+
'num_regions': {'industry-by-industry': 49, 'product-by-product': 49},
|
|
193
|
+
'num_sectors': {'industry-by-industry': 163, 'product-by-product': 200}}
|
|
194
|
+
}
|
|
195
|
+
}
|