mrio-toolbox 1.1.2__py3-none-any.whl → 1.1.3__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.

Potentially problematic release.


This version of mrio-toolbox might be problematic. Click here for more details.

Files changed (61) hide show
  1. {mrio_toolbox-1.1.2.dist-info → mrio_toolbox-1.1.3.dist-info}/METADATA +1 -1
  2. mrio_toolbox-1.1.3.dist-info/RECORD +5 -0
  3. mrio_toolbox-1.1.3.dist-info/top_level.txt +1 -0
  4. __init__.py +0 -21
  5. _parts/_Axe.py +0 -539
  6. _parts/_Part.py +0 -1739
  7. _parts/__init__.py +0 -7
  8. _parts/part_operations.py +0 -57
  9. extractors/__init__.py +0 -20
  10. extractors/downloaders.py +0 -36
  11. extractors/emerging/__init__.py +0 -3
  12. extractors/emerging/emerging_extractor.py +0 -117
  13. extractors/eora/__init__.py +0 -3
  14. extractors/eora/eora_extractor.py +0 -132
  15. extractors/exiobase/__init__.py +0 -3
  16. extractors/exiobase/exiobase_extractor.py +0 -270
  17. extractors/extractors.py +0 -81
  18. extractors/figaro/__init__.py +0 -3
  19. extractors/figaro/figaro_downloader.py +0 -280
  20. extractors/figaro/figaro_extractor.py +0 -187
  21. extractors/gloria/__init__.py +0 -3
  22. extractors/gloria/gloria_extractor.py +0 -202
  23. extractors/gtap11/__init__.py +0 -7
  24. extractors/gtap11/extraction/__init__.py +0 -3
  25. extractors/gtap11/extraction/extractor.py +0 -129
  26. extractors/gtap11/extraction/harpy_files/__init__.py +0 -6
  27. extractors/gtap11/extraction/harpy_files/_header_sets.py +0 -279
  28. extractors/gtap11/extraction/harpy_files/har_file.py +0 -262
  29. extractors/gtap11/extraction/harpy_files/har_file_io.py +0 -974
  30. extractors/gtap11/extraction/harpy_files/header_array.py +0 -300
  31. extractors/gtap11/extraction/harpy_files/sl4.py +0 -229
  32. extractors/gtap11/gtap_mrio/__init__.py +0 -6
  33. extractors/gtap11/gtap_mrio/mrio_builder.py +0 -158
  34. extractors/icio/__init__.py +0 -3
  35. extractors/icio/icio_extractor.py +0 -121
  36. extractors/wiod/__init__.py +0 -3
  37. extractors/wiod/wiod_extractor.py +0 -143
  38. mrio.py +0 -899
  39. mrio_toolbox-1.1.2.dist-info/RECORD +0 -59
  40. mrio_toolbox-1.1.2.dist-info/top_level.txt +0 -6
  41. msm/__init__.py +0 -6
  42. msm/multi_scale_mapping.py +0 -863
  43. utils/__init__.py +0 -3
  44. utils/converters/__init__.py +0 -5
  45. utils/converters/pandas.py +0 -244
  46. utils/converters/xarray.py +0 -132
  47. utils/formatting/__init__.py +0 -0
  48. utils/formatting/formatter.py +0 -527
  49. utils/loaders/__init__.py +0 -7
  50. utils/loaders/_loader.py +0 -312
  51. utils/loaders/_loader_factory.py +0 -96
  52. utils/loaders/_nc_loader.py +0 -184
  53. utils/loaders/_np_loader.py +0 -112
  54. utils/loaders/_pandas_loader.py +0 -128
  55. utils/loaders/_parameter_loader.py +0 -386
  56. utils/savers/__init__.py +0 -11
  57. utils/savers/_path_checker.py +0 -37
  58. utils/savers/_to_folder.py +0 -165
  59. utils/savers/_to_nc.py +0 -60
  60. {mrio_toolbox-1.1.2.dist-info → mrio_toolbox-1.1.3.dist-info}/WHEEL +0 -0
  61. {mrio_toolbox-1.1.2.dist-info → mrio_toolbox-1.1.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mrio_toolbox
3
- Version: 1.1.2
3
+ Version: 1.1.3
4
4
  Summary: Basic manipulation of Multi-Regional Input-Output tables.
5
5
  Author-email: Timothe Beaufils <timothe.beaufils@pik-potsdam.de>, Florian Wirth <florian.wirth@pik-potsdam.de>
6
6
  License-Expression: GPL-3.0-or-later
@@ -0,0 +1,5 @@
1
+ mrio_toolbox-1.1.3.dist-info/licenses/LICENSE,sha256=q7yPlSQr4UbocyAmi56sBygg841JSclXoeXH8eOG7xQ,35819
2
+ mrio_toolbox-1.1.3.dist-info/METADATA,sha256=pxM_3oSa6Mwe6yaPKqg0d0WH70mNETAnDYgJorbU7ys,1192
3
+ mrio_toolbox-1.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
4
+ mrio_toolbox-1.1.3.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
5
+ mrio_toolbox-1.1.3.dist-info/RECORD,,
@@ -0,0 +1 @@
1
+
__init__.py DELETED
@@ -1,21 +0,0 @@
1
- """
2
- The MRIO toolbox module provides several submodules with different functionalities:
3
-
4
- - `mrio_toolbox.mrio`: Contains the MRIO class for handling multi-regional input-output data.
5
- - `mrio_toolbox._parts`: Contains the Part and Axe classes for managing parts of MRIO data.
6
- - `mrio_toolbox.extractors`: Provides functions to extract raw MRIO data.
7
- - 'mrio_toolbox._msm': Contains the multi-scale mapping algorithm for mapping PRIMAP data into an MRIO
8
- - `mrio_toolbox._utils`: Contains utility functions for MRIO loading, saving and converting MRIO data to different formats.
9
-
10
- """
11
-
12
- from mrio_toolbox.mrio import MRIO
13
- from mrio_toolbox._parts._Part import Part,load_part
14
- from mrio_toolbox.extractors import extract_MRIO
15
- from mrio_toolbox.extractors import download_MRIO
16
-
17
- __all__ = ["MRIO",
18
- "load_part",
19
- "Part",
20
- "extract_MRIO",
21
- "download_MRIO"]
_parts/_Axe.py DELETED
@@ -1,539 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- """
3
- Definition of Part Axes
4
- """
5
-
6
- import logging
7
- import itertools
8
- import pandas as pd
9
- import numpy as np
10
- from copy import deepcopy
11
-
12
- log = logging.getLogger(__name__)
13
- class Axe:
14
- """
15
- Representation of an Axe object.
16
-
17
- An Axe holds the labels and dimensions for an MRIO Part. Axes are used
18
- to slice MRIO Parts based on labels or indices and support multi-level
19
- indexing and groupings.
20
-
21
- Instance variables
22
- ------------------
23
- labels : dict
24
- Dictionary of labels for each level of the Axe.
25
- levels : int
26
- Number of levels in the Axe.
27
- dims : list of int
28
- Number of labels for each level.
29
- dimensions : list of str
30
- Keys of the labels dictionary, representing the dimensions of the Axe.
31
- groupings : dict
32
- Groupings of the labels for each level of the Axe.
33
- mappings : dict
34
- Mappings used to convert grouping labels into indices.
35
- multipliers : dict
36
- Multipliers used to convert labels into indices.
37
- name : str
38
- Name of the Axe.
39
-
40
- Methods
41
- -------
42
- set_labels(labels):
43
- Set the labels of the Axe.
44
- update_multipliers():
45
- Update the multipliers used to convert labels into indices.
46
- squeeze():
47
- Remove levels with only one label.
48
- swap_levels(level1, level2):
49
- Swap the positions of two levels in the Axe.
50
- label(as_index=False):
51
- Generate the labels for the full axis.
52
- isin(arg, level):
53
- Check whether an element is in the labels of a given level.
54
- derive_mappings(groupings=None):
55
- Update the mappings of the Axe based on the groupings.
56
- update_groupings(groupings=None):
57
- Update the groupings of the Axe.
58
- get(args, labels=False):
59
- Get the indices corresponding to a selection on the Axe.
60
- rename_labels(old, new):
61
- Rename labels in the Axe.
62
- replace_labels(name, labels):
63
- Replace a given label in the Axe.
64
- has_dim(dim):
65
- Check whether a given dimension is in the Axe.
66
- __getitem__(*args):
67
- Indexing is passed to the `get` method.
68
- __eq__(other):
69
- Check equality between two Axe objects.
70
- __len__():
71
- Get the full label length of the Axe.
72
- """
73
-
74
- def __init__(self,labels,groupings=None,
75
- name=None):
76
- """
77
- Initialize an Axe object.
78
-
79
- Parameters
80
- ----------
81
- labels : dict or list of list of str
82
- Dictionary of labels for each level of the Axe. If a list of lists
83
- is passed, levels are set to 0, 1, 2, etc.
84
- groupings : dict, optional
85
- Dictionary of groupings for each level of the Axe. Groupings define
86
- how labels are grouped into larger categories (e.g., countries into zones).
87
- If not provided, groupings are set to the identity.
88
- name : str, optional
89
- Name of the Axe. If not provided, a name is generated automatically
90
- based on the dimensions.
91
-
92
- Raises
93
- ------
94
- TypeError
95
- If the provided labels are not a dictionary or a list of lists.
96
-
97
- Notes
98
- -----
99
- The `labels` parameter defines the structure of the Axe, while the
100
- `groupings` parameter allows grouping labels into higher-level categories.
101
- """
102
- if isinstance(labels,dict):
103
- self.labels = labels
104
- elif isinstance(labels,list):
105
- if isinstance(labels[0],dict):
106
- self.labels = dict()
107
- for label in labels:
108
- self.labels.update(label)
109
- elif not isinstance(labels[0],list):
110
- self.labels = {str(0):labels}
111
- else:
112
- self.labels = {str(i):labels[i] for i in range(len(labels))}
113
- else:
114
- raise TypeError("Labels must be a list or a dict. Input is of type "+str(type(labels)))
115
- self.levels = len(self.labels)
116
- self.dims = [len(dim) for dim in self.labels.values()]
117
- self.dimensions = [
118
- str(dim) for dim in self.labels.keys()
119
- ] #Dimensions of the Axe
120
- #Dimensions also save the order of the levels
121
- self.ndim = len(self.dims)
122
- self.update_multipliers()
123
- if groupings is None:
124
- self.groupings = {i:{} for i in self.dimensions}
125
- else:
126
- self.groupings = groupings
127
- self.mappings = dict()
128
- self.derive_mappings(groupings)
129
- if name is None:
130
- if len(self.dimensions)>1:
131
- self.name = "_".join(self.dimensions)
132
- self.name = self.dimensions[0]
133
- else:
134
- self.name = name
135
-
136
- def set_labels(self,labels):
137
- """Set the labels of the Axe
138
-
139
- Parameters
140
- ----------
141
- labels : dict or list of list of str
142
- Dict of labels for each level of the Axe.
143
- The levels are interpreted in the order of the keys.
144
- If a list of list of str is passed, levels are set to 0,1,2...
145
- """
146
- if isinstance(labels,dict):
147
- self.labels = labels
148
- elif isinstance(labels,list):
149
- if not isinstance(labels[0],list):
150
- self.labels = {str(0):labels}
151
- else:
152
- self.labels = {str(i):labels[i] for i in range(len(labels))}
153
- else:
154
- raise TypeError("Labels must be a list or a dict. Input is of type "+str(type(labels)))
155
- self.levels = len(self.labels)
156
- self.dims = [len(dim) for dim in self.labels.values()]
157
- self.dimensions = list(self.labels.keys())
158
- self.ndim = len(self.dims)
159
-
160
- def update_multipliers(self):
161
- """
162
- Update the multipliers used to convert labels into indices
163
- """
164
- multipliers = []
165
- for i in range(len(self.dims)):
166
- multipliers.append(self.dims[i]*multipliers[i-1] if i > 0 else 1)
167
- self.multipliers = { #Dictionnary of multipliers for each level
168
- i:multiplier for i,multiplier in zip(self.dimensions,multipliers[::-1])
169
- }
170
-
171
- def squeeze(self):
172
- """Remove levels with only one label"""
173
- for key in self.dimensions:
174
- if len(self.labels[key]) == 1:
175
- self.labels.pop(key)
176
- self.multipliers.pop(key)
177
- if key in self.mappings.keys():
178
- self.mappings.pop(key)
179
- self.levels = len(self.labels)
180
- self.dims = [len(dim) for dim in self.labels.values()]
181
- self.dimensions = list(self.labels.keys())
182
- self.ndim = len(self.dims)
183
-
184
-
185
- def swap_levels(self,level1,level2):
186
- """Swap the positions of two levels in the Axe
187
-
188
- Parameters
189
- ----------
190
- level1 : int
191
- Level to swap
192
- level2 : int
193
- Level to swap
194
- """
195
- if level1 not in self.labels.keys() or level2 not in self.labels.keys():
196
- raise IndexError("Levels must be in the Axe")
197
- dims = self.dimensions
198
- dims[level1],dims[level2] = dims[level2],dims[level1]
199
- self.dimensions = dims
200
- self.dims = [len(dim) for dim in self.labels.values()]
201
-
202
- def __str__(self):
203
- return f"Axe object of len {len(self)}, with {self.levels} levels: {self.dimensions}"
204
-
205
- def label(self,as_index=False):
206
- """ Generate the labels for the full axis
207
-
208
- Parameters
209
- ----------
210
- as_index : bool, optional
211
- Whether to return a Pandas MultiIndex.
212
- The default is False, in which case a list of labels is returned.
213
-
214
-
215
- Returns
216
- -------
217
- list of str
218
- Labels along the Axe
219
- """
220
- if as_index:
221
- if self.levels == 1:
222
- return pd.Index(self.labels[self.dimensions[0]],name=self.dimensions[0])
223
- return pd.MultiIndex.from_product(
224
- [self.labels[key] for key in self.dimensions],
225
- names = self.dimensions
226
- )
227
- return list(itertools.product(*[self.labels[key] for key in self.dimensions]))
228
-
229
-
230
- def isin(self,arg,level):
231
- """
232
- Assert whether an element is in the labels of a given level
233
-
234
- Parameters
235
- ----------
236
- arg : str, int or list of int,str
237
- Element to look for.
238
- level : str
239
- Key of the level to look into.
240
-
241
- Returns
242
- -------
243
- bool
244
- Whether the element is in the labels.
245
-
246
- """
247
- if "all" in arg:
248
- return True
249
- if isinstance(arg,(int,np.integer)) and arg < len(self.labels[level]):
250
- return True
251
- if isinstance(arg,str):
252
- return arg in self.labels[level] \
253
- or arg in self.mappings[level].keys()\
254
- or arg=="all"
255
- if isinstance(arg,list):
256
- for a in arg:
257
- if not self.isin(a,level):
258
- return False
259
- return True
260
- raise TypeError(
261
- "Arg must be a string, an int or a list of strings or ints."+\
262
- " Input is of type "+str(type(arg))
263
- )
264
-
265
- def derive_mappings(self,groupings=None):
266
- """Update the mappings of the Axe
267
-
268
- Mappings are defined at Axe level and derive from the current groupings
269
- Mappings are used to convert grouping labels into indices
270
-
271
- Parameters
272
- ----------
273
- groupings : dict of dict
274
- Dict of groupings for each level of the Axe.
275
- Grouping of labels into larger categories (e.g countries into zones).
276
- If groupings contain references not in the labels, these are removed.
277
- By default, groupings are set to the identity.
278
- """
279
-
280
- if groupings is None:
281
- for key in self.dimensions:
282
- self.mappings[key] = {
283
- label:[i] for i,label in enumerate(self.labels[key])
284
- }
285
- return
286
- to_sort = deepcopy(groupings)
287
- for key in self.dimensions:
288
- self.mappings[key] = dict()
289
- covered = []
290
-
291
- if to_sort is not None and key in to_sort.keys():
292
- for group in to_sort[key].keys():
293
- idlist = []
294
- for label in to_sort[key][group]:
295
- if label not in self.labels[key]\
296
- and label != "all":
297
- log.debug(
298
- f"Label {label} in group {group} is not in the labels of the Axe"
299
- )
300
- to_sort[key][group].remove(label)
301
- elif label in covered:
302
- log.warning(
303
- f"Label {label} is in multiple groups and will be ignored from group {group}"
304
- )
305
- elif label == "all":
306
- idlist = [i for i in len(self.labels[key])]
307
- covered = self.labels[key] + "all"
308
- else:
309
- idlist.append(self.labels[key].index(label))
310
- covered.append(label)
311
- to_sort[key][group] = idlist.copy()
312
- self.mappings[key] = to_sort[key].copy()
313
- else:
314
- self.mappings[key] = dict()
315
-
316
- def update_groupings(self,groupings=None):
317
- self.groupings = groupings
318
- self.derive_mappings(groupings)
319
-
320
- def get_on(self,arg,level,multiplier):
321
- """
322
- Recursively get the index of an arg on a given level
323
-
324
- Parameters
325
- ----------
326
- arg : str, int, list of str, int
327
- Element to look for.
328
- level : str
329
- Key of the level to look into.
330
- """
331
- if isinstance(arg,str):
332
- if arg == "all":
333
- return [i*multiplier for i in range(len(self.labels[level]))]
334
- if arg in self.mappings[level].keys():
335
- return [
336
- i*multiplier for i in self.mappings[level][arg]
337
- ]
338
- return [self.labels[level].index(arg)*multiplier]
339
- if isinstance(arg,(int,np.integer)):
340
- return [arg*multiplier]
341
- sel = []
342
- for a in arg:
343
- sel += self.get_on(a,level,multiplier)
344
- return sel
345
-
346
- def get_single_ax(self,args):
347
- """Make selection for single level Axes"""
348
- sel = []
349
- level = self.dimensions[0]
350
- sel.append(self.get_on(args,level,self.multipliers[level]))
351
- for level in range(1,self.levels):
352
- #Fill the rest of the selection with all elements
353
- sel.append([i*self.multipliers[level] for i in range(len(self.labels[level]))])
354
- return [sum(arg) for arg in itertools.product(*sel)]
355
-
356
- def get_labels(self):
357
- """Get the labels of the Axe as a dict"""
358
- return {key:self.labels[key] for key in self.dimensions}
359
-
360
- def get_groupings(self):
361
- """Get the groupings of the Axe"""
362
- return self.groupings
363
-
364
- def get_labs(self,args):
365
- """Extract the labels corresponding to a given selection of multiple levels
366
-
367
- Parameters
368
- ----------
369
- args : list of ints
370
- Cleaned selection of indices
371
-
372
- Returns
373
- -------
374
- dict
375
- Dict of labels for each level
376
- """
377
- labels = dict()
378
- for i,key in enumerate(self.dimensions):
379
- if isinstance(args[i],(str)):
380
- labels[key] = [args[i]]
381
-
382
- else:
383
- labels[key] = [
384
- self.labels[key][j//self.multipliers[key]] for j in args[i]
385
- ]
386
- return labels
387
-
388
- def get(self,args,labels=False):
389
- """
390
- Get the indices corresponding to a selection on the Axe
391
-
392
- Parameters
393
- ----------
394
- args : str, int, dict, list of str, int
395
- Arguments to select on the Axe.
396
- If a dict is passed, it is assumed that the keys are the dimensions of the Axe.
397
- If a list is passed, it is assumed that the first element is the selection on the first level,
398
- the second on the second level, etc.
399
- If the selection on multipler levels fails, the selection is assumed to be on the first level only.
400
- labels : bool, optional
401
- Whether to return the labels of the selection, by default False
402
-
403
- Returns
404
- -------
405
- list of int or (list of ints, dict, dict)
406
- If labels is False, returns the indices of the selection.
407
- If labels is True, returns the indices of the selection,
408
- the labels of the selection and the groupings of the Axe.
409
- """
410
- if isinstance(args,(int,str,np.integer)):
411
- if args == "all":
412
- #Shortcut for all elements
413
- sel = [i for i in range(len(self))]
414
- if labels:
415
- return sel,self.labels.copy(),self.groupings
416
- return sel
417
- args = [args]
418
- if all(isinstance(arg,(int,np.integer)) for arg in args):
419
- #Shortcut for int based selection
420
- if labels:
421
- labels = self.label().copy()
422
- labs = [labels[arg] for arg in args]
423
- return args,labs,self.groupings
424
- return args
425
- if self.levels == 1:
426
- if isinstance(args,dict):
427
- args = list(args.values())
428
- sel = self.get_on(args,self.dimensions[0],1)
429
- if labels:
430
- labs = {
431
- self.dimensions[0] : [self.labels[self.dimensions[0]][i] for i in sel]
432
- }
433
- return sel,labs,self.groupings
434
- return sel
435
- sel = []
436
-
437
- #Preformat the args input
438
- if isinstance(args,dict):
439
- #Convert into a list
440
- filled = []
441
- for key in self.dimensions:
442
- if key not in args.keys():
443
- filled.append(["all"])
444
- else:
445
- if isinstance(args[key],list):
446
- filled.append(args[key])
447
- else:
448
- filled.append([args[key]])
449
- if not all([key in self.dimensions for key in args.keys()]):
450
- raise IndexError(f"Keys {args.keys()} are invalid in Axe with dimensions {self.dimensions}")
451
- args = filled
452
-
453
- if len(args) > self.levels:
454
- #If the args length exceeds the number of levels,
455
- #it is assumed that the selection is on the first level only
456
- return self.get_single_ax(args)
457
- #Otherwise, try to select on each level
458
- try:
459
- for level,arg in enumerate(args):
460
- lname = self.dimensions[level]
461
- sel.append(self.get_on(
462
- arg,lname,self.multipliers[lname]
463
- ))
464
- for other_dim in range(level+1,self.levels):
465
- lname = self.dimensions[other_dim]
466
- sel.append(
467
- self.get_on(
468
- "all",lname,self.multipliers[lname])
469
- )
470
- composed = [sum(arg) for arg in itertools.product(*sel)]
471
- if labels:
472
- labs = self.get_labs(sel)
473
- return composed,labs,self.groupings
474
- return composed
475
- except IndexError:
476
- #If it fails, try again on a single ax
477
- return self.get_single_ax(args)
478
-
479
- def rename_labels(self,old,new):
480
- """
481
- Rename labels in the Axes
482
-
483
- Parameters
484
- ----------
485
- old : str
486
- Former label name
487
- new : str
488
- New name
489
- """
490
- if old not in self.labels.keys():
491
- raise IndexError(f"Label {old} not in the Axe")
492
- self.labels = { (new if key == old else key): val
493
- for key, val in self.labels.items()}
494
- self.mappints = { (new if key == old else key): val
495
- for key, val in self.mappings.items()}
496
- self.dimensions = list(self.labels.keys())
497
- self.update_multipliers()
498
-
499
- def replace_labels(self,name,labels):
500
- """
501
- Replace a given label
502
-
503
- Parameters
504
- ----------
505
- name : str
506
- Name of the level to replace
507
- labels : dict
508
- New labels
509
- """
510
- self.labels.update(labels)
511
- if name != list(labels.keys())[0]:
512
- self.labels.pop(name)
513
- self.dimensions = list(self.labels.keys())
514
- self.mappings[labels.keys()[0]] = self.mappings.pop(name)
515
- self.update_multipliers()
516
-
517
- def __getitem__(self,*a):
518
- """
519
- Indexing are passed to the get method
520
- """
521
- return self.get(*a)
522
-
523
- def __eq__(self,other):
524
- if isinstance(other,Axe):
525
- if self.labels == other.labels:
526
- return True
527
- return False
528
-
529
-
530
- def has_dim(self,dim):
531
- """Check whether a given dimension is in the Axe"""
532
- return dim in self.dimensions
533
-
534
- def __len__(self):
535
- """Get the full label length of the Axe"""
536
- length = 1
537
- for dim in self.labels.values():
538
- length *= len(dim)
539
- return length