bw-processing 0.9.6__tar.gz → 1.1__tar.gz
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.
- bw_processing-1.1/MANIFEST.in +3 -0
- {bw_processing-0.9.6/bw_processing.egg-info → bw_processing-1.1}/PKG-INFO +4 -3
- {bw_processing-0.9.6 → bw_processing-1.1}/README.md +1 -1
- {bw_processing-0.9.6 → bw_processing-1.1}/pyproject.toml +3 -1
- bw_processing-1.1/src/bw_processing/__init__.py +52 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/constants.py +2 -1
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/datapackage.py +53 -7
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/indexing.py +2 -2
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/io_helpers.py +4 -4
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/io_parquet_helpers.py +2 -2
- bw_processing-1.1/src/bw_processing/matrix_entry.py +112 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/merging.py +3 -3
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/unique_fields.py +1 -1
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/utils.py +3 -3
- {bw_processing-0.9.6 → bw_processing-1.1/src/bw_processing.egg-info}/PKG-INFO +4 -3
- bw_processing-1.1/src/bw_processing.egg-info/SOURCES.txt +52 -0
- bw_processing-1.1/tests/test_array_creation.py +14 -0
- bw_processing-1.1/tests/test_datapackage.py +499 -0
- bw_processing-1.1/tests/test_filesystem.py +33 -0
- bw_processing-1.1/tests/test_filtered_datapackage.py +151 -0
- bw_processing-1.1/tests/test_indexing.py +384 -0
- bw_processing-1.1/tests/test_integration.py +472 -0
- bw_processing-1.1/tests/test_interfaces.py +113 -0
- bw_processing-1.1/tests/test_io_parquet_helpers.py +138 -0
- bw_processing-1.1/tests/test_io_pyarrow_helpers.py +66 -0
- bw_processing-1.1/tests/test_loading.py +64 -0
- bw_processing-1.1/tests/test_matrix_entry.py +158 -0
- bw_processing-1.1/tests/test_merging.py +369 -0
- bw_processing-1.1/tests/test_proxies.py +27 -0
- bw_processing-1.1/tests/test_unique_fields.py +139 -0
- bw_processing-0.9.6/MANIFEST.in +0 -3
- bw_processing-0.9.6/bw_processing/__init__.py +0 -48
- bw_processing-0.9.6/bw_processing.egg-info/SOURCES.txt +0 -57
- bw_processing-0.9.6/dev/calculation_package.py +0 -179
- bw_processing-0.9.6/dev/loading.py +0 -85
- bw_processing-0.9.6/dev/processed_package.py +0 -261
- bw_processing-0.9.6/dev/resources.py +0 -32
- bw_processing-0.9.6/dev/speed_tests.py +0 -47
- bw_processing-0.9.6/docs/conf.py +0 -109
- {bw_processing-0.9.6 → bw_processing-1.1}/LICENSE +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1}/setup.cfg +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/array_creation.py +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/errors.py +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/__init__.py +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/another name.indices.parquet +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.data.parquet +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.distributions.parquet +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.flip.parquet +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.indices.parquet +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/some name.data.parquet +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/some name.flip.parquet +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/some name.indices.parquet +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_2.zip +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/interfaces.py +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/parquet_files.py +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/simple.zip +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/filesystem.py +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/io_pyarrow_helpers.py +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/proxies.py +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing.egg-info/dependency_links.txt +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing.egg-info/requires.txt +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing.egg-info/top_level.txt +0 -0
- {bw_processing-0.9.6 → bw_processing-1.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: bw_processing
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.1
|
|
4
4
|
Summary: Foo
|
|
5
5
|
Author-email: Chris Mutel <cmutel@gmail.com>
|
|
6
6
|
Maintainer-email: Chris Mutel <cmutel@gmail.com>
|
|
@@ -38,6 +38,7 @@ Requires-Dist: pytest; extra == "dev"
|
|
|
38
38
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
39
39
|
Requires-Dist: pytest-randomly; extra == "dev"
|
|
40
40
|
Requires-Dist: setuptools; extra == "dev"
|
|
41
|
+
Dynamic: license-file
|
|
41
42
|
|
|
42
43
|
# bw-processing
|
|
43
44
|
|
|
@@ -81,7 +82,7 @@ The [Brightway LCA framework](https://brightway.dev/) has stored data used in co
|
|
|
81
82
|
* **Support for vector and array data**. Vector (i.e. only one possible value per input) and array (i.e. many possible values, also called presamples) data are now both natively supported in data packages.
|
|
82
83
|
* **Portability**. Processed arrays can include metadata that allows for reindexing on other machines, so that processed arrays can be distributed and reused. Before, this was not possible, as integer IDs were randomly assigned on each computer, and would be different from machine to machine or even across Brightway projects.
|
|
83
84
|
* **Dynamic data sources**. Instead of requiring that data for matrix construction be present and savedd on disk, it can now be generated dynamically, either through code running locally or on another computer system. This is a big step towards embeddding life cycle assessment in a web of environmental models.
|
|
84
|
-
* **Use [
|
|
85
|
+
* **Use [fsspec](https://filesystem-spec.readthedocs.io/en/latest/) for file IO**. The use of this library allows for data packages to be stored on your local computer, or on [many logical or virtual file systems](https://docs.pyfilesystem.org/en/latest/guide.html).
|
|
85
86
|
* **Simpler handling of numeric values whose sign should be flipped**. Sometimes it is more convenient to specify positive numbers in dataset definitions, even though such numbers should be negative when inserted into the resulting matrices. For example, in the technosphere matrix in life cycle assessment, products produced are positive and products consumed are negative, though both values are given as positive in datasets. Brightway used to use a type mapping dictionary to indicate which values in a matrix should have their sign flipped after insertion. Such mapping dictionaries are brittle and inelegant. `bw_processing` uses an optional boolean vector, called `flip`, to indicate if any values should be flipped.
|
|
86
87
|
* **Separation of uncertainty distribution parameters from other data**. Fitting data to a [probability density function](https://en.wikipedia.org/wiki/Probability_density_function) (PDF), or an estimate of such a PDF, is only one approach to quantitative uncertainty analysis. We would like to support other approaches, including [direct sampling from real data](https://github.com/PascalLesage/presamples/). Therefore, uncertainty distribution parameters are stored separately, only loaded if needed, and are only one way to express quantitative uncertainty.
|
|
87
88
|
|
|
@@ -40,7 +40,7 @@ The [Brightway LCA framework](https://brightway.dev/) has stored data used in co
|
|
|
40
40
|
* **Support for vector and array data**. Vector (i.e. only one possible value per input) and array (i.e. many possible values, also called presamples) data are now both natively supported in data packages.
|
|
41
41
|
* **Portability**. Processed arrays can include metadata that allows for reindexing on other machines, so that processed arrays can be distributed and reused. Before, this was not possible, as integer IDs were randomly assigned on each computer, and would be different from machine to machine or even across Brightway projects.
|
|
42
42
|
* **Dynamic data sources**. Instead of requiring that data for matrix construction be present and savedd on disk, it can now be generated dynamically, either through code running locally or on another computer system. This is a big step towards embeddding life cycle assessment in a web of environmental models.
|
|
43
|
-
* **Use [
|
|
43
|
+
* **Use [fsspec](https://filesystem-spec.readthedocs.io/en/latest/) for file IO**. The use of this library allows for data packages to be stored on your local computer, or on [many logical or virtual file systems](https://docs.pyfilesystem.org/en/latest/guide.html).
|
|
44
44
|
* **Simpler handling of numeric values whose sign should be flipped**. Sometimes it is more convenient to specify positive numbers in dataset definitions, even though such numbers should be negative when inserted into the resulting matrices. For example, in the technosphere matrix in life cycle assessment, products produced are positive and products consumed are negative, though both values are given as positive in datasets. Brightway used to use a type mapping dictionary to indicate which values in a matrix should have their sign flipped after insertion. Such mapping dictionaries are brittle and inelegant. `bw_processing` uses an optional boolean vector, called `flip`, to indicate if any values should be flipped.
|
|
45
45
|
* **Separation of uncertainty distribution parameters from other data**. Fitting data to a [probability density function](https://en.wikipedia.org/wiki/Probability_density_function) (PDF), or an estimate of such a PDF, is only one approach to quantitative uncertainty analysis. We would like to support other approaches, including [direct sampling from real data](https://github.com/PascalLesage/presamples/). Therefore, uncertainty distribution parameters are stored separately, only loaded if needed, and are only one way to express quantitative uncertainty.
|
|
46
46
|
|
|
@@ -66,7 +66,9 @@ dev = [
|
|
|
66
66
|
[tool.setuptools]
|
|
67
67
|
license-files = ["LICENSE"]
|
|
68
68
|
include-package-data = true
|
|
69
|
-
|
|
69
|
+
|
|
70
|
+
[tool.setuptools.packages.find]
|
|
71
|
+
where = ["src"]
|
|
70
72
|
|
|
71
73
|
[tool.setuptools.dynamic]
|
|
72
74
|
version = {attr = "bw_processing.__version__"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
__all__ = (
|
|
2
|
+
"__version__",
|
|
3
|
+
"as_unique_attributes",
|
|
4
|
+
"as_unique_attributes_dataframe",
|
|
5
|
+
"clean_datapackage_name",
|
|
6
|
+
"create_array",
|
|
7
|
+
"create_datapackage",
|
|
8
|
+
"create_datapackage_from_entries",
|
|
9
|
+
"create_structured_array",
|
|
10
|
+
"Datapackage",
|
|
11
|
+
"DatapackageBase",
|
|
12
|
+
"DEFAULT_LICENSES",
|
|
13
|
+
"examples_dir",
|
|
14
|
+
"FilteredDatapackage",
|
|
15
|
+
"generic_directory_filesystem",
|
|
16
|
+
"generic_zipfile_filesystem",
|
|
17
|
+
"INDICES_DTYPE",
|
|
18
|
+
"load_datapackage",
|
|
19
|
+
"MatrixEntry",
|
|
20
|
+
"MatrixName",
|
|
21
|
+
"MatrixSerializeFormat",
|
|
22
|
+
"md5",
|
|
23
|
+
"merge_datapackages_with_mask",
|
|
24
|
+
"reindex",
|
|
25
|
+
"reset_index",
|
|
26
|
+
"safe_filename",
|
|
27
|
+
"simple_graph",
|
|
28
|
+
"UNCERTAINTY_DTYPE",
|
|
29
|
+
"UndefinedInterface",
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
__version__ = "1.1"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
from bw_processing.array_creation import create_array, create_structured_array
|
|
36
|
+
from bw_processing.constants import DEFAULT_LICENSES, INDICES_DTYPE, UNCERTAINTY_DTYPE, MatrixSerializeFormat
|
|
37
|
+
from bw_processing.datapackage import (
|
|
38
|
+
Datapackage,
|
|
39
|
+
DatapackageBase,
|
|
40
|
+
FilteredDatapackage,
|
|
41
|
+
create_datapackage,
|
|
42
|
+
load_datapackage,
|
|
43
|
+
simple_graph,
|
|
44
|
+
)
|
|
45
|
+
from bw_processing.examples import examples_dir
|
|
46
|
+
from bw_processing.filesystem import clean_datapackage_name, md5, safe_filename
|
|
47
|
+
from bw_processing.indexing import reindex, reset_index
|
|
48
|
+
from bw_processing.io_helpers import generic_directory_filesystem, generic_zipfile_filesystem
|
|
49
|
+
from bw_processing.matrix_entry import MatrixEntry, MatrixName, create_datapackage_from_entries
|
|
50
|
+
from bw_processing.merging import merge_datapackages_with_mask
|
|
51
|
+
from bw_processing.proxies import UndefinedInterface
|
|
52
|
+
from bw_processing.unique_fields import as_unique_attributes, as_unique_attributes_dataframe
|
|
@@ -4,6 +4,7 @@ from enum import Enum
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
|
|
6
6
|
MAX_SIGNED_32BIT_INT = 2147483647
|
|
7
|
+
MAX_SIGNED_64BIT_INT = 9223372036854775807
|
|
7
8
|
|
|
8
9
|
# We could try to save space by not storing the columns
|
|
9
10
|
# `row_index` and `col_index`, and add them after loading from
|
|
@@ -20,7 +21,7 @@ UNCERTAINTY_DTYPE = [
|
|
|
20
21
|
("maximum", np.float32),
|
|
21
22
|
("negative", bool),
|
|
22
23
|
]
|
|
23
|
-
INDICES_DTYPE = [("row", np.
|
|
24
|
+
INDICES_DTYPE = [("row", np.int64), ("col", np.int64)]
|
|
24
25
|
|
|
25
26
|
NAME_RE = re.compile(r"^[\w\-\.]*$")
|
|
26
27
|
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import datetime
|
|
2
2
|
import uuid
|
|
3
|
+
import warnings
|
|
3
4
|
from abc import ABC
|
|
4
5
|
from functools import partial
|
|
5
|
-
from typing import Any, Dict, List, Optional, Union
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from bw_processing.matrix_entry import MatrixEntry
|
|
6
10
|
|
|
7
11
|
import numpy as np
|
|
8
12
|
import pandas as pd
|
|
@@ -11,16 +15,18 @@ from fsspec import AbstractFileSystem
|
|
|
11
15
|
# Use this instead of fsspec MemoryFileSystem because that is a singleton!?
|
|
12
16
|
from morefs.dict import DictFS
|
|
13
17
|
|
|
14
|
-
from .constants import (
|
|
18
|
+
from bw_processing.constants import (
|
|
15
19
|
DEFAULT_LICENSES,
|
|
16
20
|
INDICES_DTYPE,
|
|
21
|
+
MAX_SIGNED_32BIT_INT,
|
|
22
|
+
MAX_SIGNED_64BIT_INT,
|
|
17
23
|
NUMPY_SERIALIZE_FORMAT_EXTENSION,
|
|
18
24
|
NUMPY_SERIALIZE_FORMAT_NAME,
|
|
19
25
|
PARQUET_SERIALIZE_FORMAT_EXTENSION,
|
|
20
26
|
PARQUET_SERIALIZE_FORMAT_NAME,
|
|
21
27
|
MatrixSerializeFormat,
|
|
22
28
|
)
|
|
23
|
-
from .errors import (
|
|
29
|
+
from bw_processing.errors import (
|
|
24
30
|
Closed,
|
|
25
31
|
InvalidMimetype,
|
|
26
32
|
LengthMismatch,
|
|
@@ -29,10 +35,10 @@ from .errors import (
|
|
|
29
35
|
ShapeMismatch,
|
|
30
36
|
WrongDatatype,
|
|
31
37
|
)
|
|
32
|
-
from .filesystem import clean_datapackage_name
|
|
33
|
-
from .io_helpers import file_reader, file_writer
|
|
34
|
-
from .proxies import Proxy, UndefinedInterface
|
|
35
|
-
from .utils import check_name, check_suffix, load_bytes, resolve_dict_iterator, utc_now
|
|
38
|
+
from bw_processing.filesystem import clean_datapackage_name
|
|
39
|
+
from bw_processing.io_helpers import file_reader, file_writer
|
|
40
|
+
from bw_processing.proxies import Proxy, UndefinedInterface
|
|
41
|
+
from bw_processing.utils import check_name, check_suffix, load_bytes, resolve_dict_iterator, utc_now
|
|
36
42
|
|
|
37
43
|
|
|
38
44
|
class DatapackageBase(ABC):
|
|
@@ -257,6 +263,12 @@ class DatapackageBase(ABC):
|
|
|
257
263
|
|
|
258
264
|
self.data[index] = resource
|
|
259
265
|
|
|
266
|
+
def get_max_index_value(self) -> int:
|
|
267
|
+
"""Get maximum index value (max signed 32 or 64 bit integer) for this datapackage"""
|
|
268
|
+
if self.metadata.get("64_bit_indices"):
|
|
269
|
+
return MAX_SIGNED_64BIT_INT
|
|
270
|
+
return MAX_SIGNED_32BIT_INT
|
|
271
|
+
|
|
260
272
|
|
|
261
273
|
class FilteredDatapackage(DatapackageBase):
|
|
262
274
|
"""A subset of a datapackage. Used in matrix construction or other data manipulation operations.
|
|
@@ -360,6 +372,7 @@ class Datapackage(DatapackageBase):
|
|
|
360
372
|
"combinatorial": combinatorial,
|
|
361
373
|
"sequential": sequential,
|
|
362
374
|
"seed": seed,
|
|
375
|
+
"64_bit_indices": True,
|
|
363
376
|
"sum_intra_duplicates": sum_intra_duplicates,
|
|
364
377
|
"sum_inter_duplicates": sum_inter_duplicates,
|
|
365
378
|
"matrix_serialize_format_type": matrix_serialize_format_type.value,
|
|
@@ -439,6 +452,30 @@ class Datapackage(DatapackageBase):
|
|
|
439
452
|
**kwargs,
|
|
440
453
|
)
|
|
441
454
|
|
|
455
|
+
def add_entries(
|
|
456
|
+
self,
|
|
457
|
+
*,
|
|
458
|
+
matrix: str,
|
|
459
|
+
entries: list["MatrixEntry"],
|
|
460
|
+
name: Optional[str] = None,
|
|
461
|
+
) -> None:
|
|
462
|
+
"""Add matrix data from a list of :class:`MatrixEntry` objects.
|
|
463
|
+
|
|
464
|
+
High-level convenience method that does not require working directly
|
|
465
|
+
with NumPy arrays.
|
|
466
|
+
|
|
467
|
+
Args:
|
|
468
|
+
matrix: Name of the target matrix (e.g. ``"technosphere"``).
|
|
469
|
+
entries: List of :class:`.MatrixEntry` instances.
|
|
470
|
+
name: Optional resource group name; auto-generated if omitted.
|
|
471
|
+
"""
|
|
472
|
+
self.add_persistent_vector_from_iterator(
|
|
473
|
+
matrix=matrix,
|
|
474
|
+
name=name,
|
|
475
|
+
dict_iterator=(e.as_dict() for e in entries),
|
|
476
|
+
nrows=len(entries),
|
|
477
|
+
)
|
|
478
|
+
|
|
442
479
|
def add_persistent_vector(
|
|
443
480
|
self,
|
|
444
481
|
*, # Forces use of keyword arguments
|
|
@@ -1082,6 +1119,10 @@ def load_datapackage(
|
|
|
1082
1119
|
def simple_graph(data: dict, fs: Optional[AbstractFileSystem] = None, **metadata) -> Datapackage:
|
|
1083
1120
|
"""Easy creation of simple datapackages with only persistent vectors.
|
|
1084
1121
|
|
|
1122
|
+
.. deprecated::
|
|
1123
|
+
Use :func:`bw_processing.matrix_entry.create_datapackage_from_entries` with
|
|
1124
|
+
:class:`bw_processing.matrix_entry.MatrixEntry` objects instead.
|
|
1125
|
+
|
|
1085
1126
|
Args:
|
|
1086
1127
|
* data: is a dictionary.
|
|
1087
1128
|
The data dictionary has the form::
|
|
@@ -1102,6 +1143,11 @@ def simple_graph(data: dict, fs: Optional[AbstractFileSystem] = None, **metadata
|
|
|
1102
1143
|
the datapackage.
|
|
1103
1144
|
|
|
1104
1145
|
"""
|
|
1146
|
+
warnings.warn(
|
|
1147
|
+
"simple_graph is deprecated; use create_datapackage_from_entries with MatrixEntry objects instead.",
|
|
1148
|
+
DeprecationWarning,
|
|
1149
|
+
stacklevel=2,
|
|
1150
|
+
)
|
|
1105
1151
|
dp = create_datapackage(fs=fs or DictFS(), **metadata)
|
|
1106
1152
|
for key, value in data.items():
|
|
1107
1153
|
indices_array = np.array([row[:2] for row in value], dtype=INDICES_DTYPE)
|
|
@@ -5,8 +5,8 @@ import numpy as np
|
|
|
5
5
|
import pandas as pd
|
|
6
6
|
from fsspec import AbstractFileSystem
|
|
7
7
|
|
|
8
|
-
from .datapackage import Datapackage, load_datapackage
|
|
9
|
-
from .errors import NonUnique
|
|
8
|
+
from bw_processing.datapackage import Datapackage, load_datapackage
|
|
9
|
+
from bw_processing.errors import NonUnique
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def _get_csv_data(
|
|
@@ -11,12 +11,12 @@ from fsspec.implementations.local import LocalFileSystem
|
|
|
11
11
|
from fsspec.implementations.zip import ZipFileSystem
|
|
12
12
|
from morefs.dict import DictFS
|
|
13
13
|
|
|
14
|
-
from .constants import MatrixSerializeFormat
|
|
15
|
-
from .errors import InvalidMimetype
|
|
16
|
-
from .proxies import Proxy
|
|
14
|
+
from bw_processing.constants import MatrixSerializeFormat
|
|
15
|
+
from bw_processing.errors import InvalidMimetype
|
|
16
|
+
from bw_processing.proxies import Proxy
|
|
17
17
|
|
|
18
18
|
try:
|
|
19
|
-
from .io_parquet_helpers import load_ndarray_from_parquet, save_arr_to_parquet
|
|
19
|
+
from bw_processing.io_parquet_helpers import load_ndarray_from_parquet, save_arr_to_parquet
|
|
20
20
|
|
|
21
21
|
PARQUET = True
|
|
22
22
|
except ImportError:
|
|
@@ -13,8 +13,8 @@ import numpy
|
|
|
13
13
|
import numpy as np
|
|
14
14
|
import pyarrow.parquet as pq
|
|
15
15
|
|
|
16
|
-
from .errors import WrongDatatype
|
|
17
|
-
from .io_pyarrow_helpers import (
|
|
16
|
+
from bw_processing.errors import WrongDatatype
|
|
17
|
+
from bw_processing.io_pyarrow_helpers import (
|
|
18
18
|
numpy_distributions_vector_to_pyarrow_distributions_vector_table,
|
|
19
19
|
numpy_generic_matrix_to_pyarrow_generic_matrix_table,
|
|
20
20
|
numpy_generic_vector_to_pyarrow_generic_vector_table,
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import math
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MatrixName(str, Enum):
|
|
7
|
+
"""Standard matrix names used in Brightway.
|
|
8
|
+
|
|
9
|
+
Because this is a ``str`` enum, members can be used anywhere a plain
|
|
10
|
+
string is accepted — no ``.value`` needed::
|
|
11
|
+
|
|
12
|
+
MatrixEntry(row=1, col=4, amount=2.5) # inside a dict keyed by MatrixName
|
|
13
|
+
dp.add_entries(matrix=MatrixName.technosphere, entries=[...])
|
|
14
|
+
|
|
15
|
+
Derived libraries may define additional matrices as plain strings;
|
|
16
|
+
these three cover the core Brightway LCA workflow.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
technosphere = "technosphere_matrix"
|
|
20
|
+
biosphere = "biosphere_matrix"
|
|
21
|
+
characterization = "characterization_matrix"
|
|
22
|
+
|
|
23
|
+
def __str__(self) -> str:
|
|
24
|
+
return self.value
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclasses.dataclass(frozen=True)
|
|
28
|
+
class MatrixEntry:
|
|
29
|
+
"""A single entry destined for a matrix cell.
|
|
30
|
+
|
|
31
|
+
Multiple instances with the same (row, col) are summed during matrix
|
|
32
|
+
construction, so this is not necessarily the final cell value.
|
|
33
|
+
|
|
34
|
+
Field names and defaults match those expected by bw_processing's
|
|
35
|
+
``dictionary_formatter``. Convert to a plain dict with ``as_dict()``
|
|
36
|
+
before passing to bw_processing internals.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
row: Integer row index in the target matrix.
|
|
40
|
+
col: Integer column index in the target matrix.
|
|
41
|
+
amount: The numeric value to place at (row, col).
|
|
42
|
+
flip: If True, multiply the value by -1 when building the matrix.
|
|
43
|
+
uncertainty_type: Probability distribution type (0 = no uncertainty,
|
|
44
|
+
2 = lognormal, 3 = normal, etc. — see stats_arrays for full list).
|
|
45
|
+
loc: Distribution location parameter. For lognormal this is the log
|
|
46
|
+
of the median; defaults to NaN (no uncertainty).
|
|
47
|
+
scale: Distribution scale parameter (e.g. standard deviation).
|
|
48
|
+
shape: Distribution shape parameter.
|
|
49
|
+
minimum: Lower bound for distribution sampling.
|
|
50
|
+
maximum: Upper bound for distribution sampling.
|
|
51
|
+
negative: Whether the underlying value is negative.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
row: int
|
|
55
|
+
col: int
|
|
56
|
+
amount: float
|
|
57
|
+
flip: bool = False
|
|
58
|
+
uncertainty_type: int = 0
|
|
59
|
+
loc: float = math.nan
|
|
60
|
+
scale: float = math.nan
|
|
61
|
+
shape: float = math.nan
|
|
62
|
+
minimum: float = math.nan
|
|
63
|
+
maximum: float = math.nan
|
|
64
|
+
negative: bool = False
|
|
65
|
+
|
|
66
|
+
def as_dict(self) -> dict:
|
|
67
|
+
return dataclasses.asdict(self)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def create_datapackage_from_entries(
|
|
71
|
+
data: dict,
|
|
72
|
+
fs=None,
|
|
73
|
+
**metadata,
|
|
74
|
+
):
|
|
75
|
+
"""Create a datapackage from a dictionary of :class:`MatrixEntry` lists.
|
|
76
|
+
|
|
77
|
+
This is the recommended high-level entry point for building datapackages
|
|
78
|
+
without working directly with NumPy arrays.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
data: Dictionary mapping matrix names to lists of :class:`MatrixEntry`
|
|
82
|
+
objects. Use :class:`MatrixName` members as keys for the standard
|
|
83
|
+
Brightway matrices; derived libraries may use plain strings for
|
|
84
|
+
additional matrices::
|
|
85
|
+
|
|
86
|
+
{
|
|
87
|
+
MatrixName.technosphere: [
|
|
88
|
+
MatrixEntry(row=1, col=4, amount=2.5),
|
|
89
|
+
MatrixEntry(row=2, col=5, amount=7.0, flip=True),
|
|
90
|
+
],
|
|
91
|
+
MatrixName.biosphere: [
|
|
92
|
+
MatrixEntry(row=10, col=4, amount=0.3),
|
|
93
|
+
],
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
fs: Optional filesystem. Defaults to an in-memory filesystem.
|
|
97
|
+
**metadata: Additional keyword arguments passed to
|
|
98
|
+
:func:`create_datapackage` (e.g. ``name``, ``id_``).
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
A :class:`Datapackage` instance.
|
|
102
|
+
"""
|
|
103
|
+
from bw_processing.datapackage import create_datapackage
|
|
104
|
+
|
|
105
|
+
dp = create_datapackage(fs=fs, **metadata)
|
|
106
|
+
for matrix_name, entries in data.items():
|
|
107
|
+
dp.add_entries(
|
|
108
|
+
matrix=matrix_name,
|
|
109
|
+
entries=entries,
|
|
110
|
+
name=f"{matrix_name}-data",
|
|
111
|
+
)
|
|
112
|
+
return dp
|
|
@@ -7,9 +7,9 @@ import pandas as pd
|
|
|
7
7
|
from fsspec import AbstractFileSystem
|
|
8
8
|
from morefs.dict import DictFS
|
|
9
9
|
|
|
10
|
-
from .datapackage import DatapackageBase, create_datapackage
|
|
11
|
-
from .errors import LengthMismatch
|
|
12
|
-
from .io_helpers import file_writer
|
|
10
|
+
from bw_processing.datapackage import DatapackageBase, create_datapackage
|
|
11
|
+
from bw_processing.errors import LengthMismatch
|
|
12
|
+
from bw_processing.io_helpers import file_writer
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def mask_resource(obj: Any, mask: np.ndarray) -> Any:
|
|
@@ -6,9 +6,9 @@ from typing import Any, Union
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
from numpy.lib.recfunctions import repack_fields
|
|
8
8
|
|
|
9
|
-
from .array_creation import create_structured_array
|
|
10
|
-
from .constants import INDICES_DTYPE, NAME_RE, UNCERTAINTY_DTYPE
|
|
11
|
-
from .errors import InvalidName
|
|
9
|
+
from bw_processing.array_creation import create_structured_array
|
|
10
|
+
from bw_processing.constants import INDICES_DTYPE, NAME_RE, UNCERTAINTY_DTYPE
|
|
11
|
+
from bw_processing.errors import InvalidName
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def load_bytes(obj: Any) -> Any:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: bw_processing
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.1
|
|
4
4
|
Summary: Foo
|
|
5
5
|
Author-email: Chris Mutel <cmutel@gmail.com>
|
|
6
6
|
Maintainer-email: Chris Mutel <cmutel@gmail.com>
|
|
@@ -38,6 +38,7 @@ Requires-Dist: pytest; extra == "dev"
|
|
|
38
38
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
39
39
|
Requires-Dist: pytest-randomly; extra == "dev"
|
|
40
40
|
Requires-Dist: setuptools; extra == "dev"
|
|
41
|
+
Dynamic: license-file
|
|
41
42
|
|
|
42
43
|
# bw-processing
|
|
43
44
|
|
|
@@ -81,7 +82,7 @@ The [Brightway LCA framework](https://brightway.dev/) has stored data used in co
|
|
|
81
82
|
* **Support for vector and array data**. Vector (i.e. only one possible value per input) and array (i.e. many possible values, also called presamples) data are now both natively supported in data packages.
|
|
82
83
|
* **Portability**. Processed arrays can include metadata that allows for reindexing on other machines, so that processed arrays can be distributed and reused. Before, this was not possible, as integer IDs were randomly assigned on each computer, and would be different from machine to machine or even across Brightway projects.
|
|
83
84
|
* **Dynamic data sources**. Instead of requiring that data for matrix construction be present and savedd on disk, it can now be generated dynamically, either through code running locally or on another computer system. This is a big step towards embeddding life cycle assessment in a web of environmental models.
|
|
84
|
-
* **Use [
|
|
85
|
+
* **Use [fsspec](https://filesystem-spec.readthedocs.io/en/latest/) for file IO**. The use of this library allows for data packages to be stored on your local computer, or on [many logical or virtual file systems](https://docs.pyfilesystem.org/en/latest/guide.html).
|
|
85
86
|
* **Simpler handling of numeric values whose sign should be flipped**. Sometimes it is more convenient to specify positive numbers in dataset definitions, even though such numbers should be negative when inserted into the resulting matrices. For example, in the technosphere matrix in life cycle assessment, products produced are positive and products consumed are negative, though both values are given as positive in datasets. Brightway used to use a type mapping dictionary to indicate which values in a matrix should have their sign flipped after insertion. Such mapping dictionaries are brittle and inelegant. `bw_processing` uses an optional boolean vector, called `flip`, to indicate if any values should be flipped.
|
|
86
87
|
* **Separation of uncertainty distribution parameters from other data**. Fitting data to a [probability density function](https://en.wikipedia.org/wiki/Probability_density_function) (PDF), or an estimate of such a PDF, is only one approach to quantitative uncertainty analysis. We would like to support other approaches, including [direct sampling from real data](https://github.com/PascalLesage/presamples/). Therefore, uncertainty distribution parameters are stored separately, only loaded if needed, and are only one way to express quantitative uncertainty.
|
|
87
88
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
README.md
|
|
4
|
+
pyproject.toml
|
|
5
|
+
src/bw_processing/__init__.py
|
|
6
|
+
src/bw_processing/array_creation.py
|
|
7
|
+
src/bw_processing/constants.py
|
|
8
|
+
src/bw_processing/datapackage.py
|
|
9
|
+
src/bw_processing/errors.py
|
|
10
|
+
src/bw_processing/filesystem.py
|
|
11
|
+
src/bw_processing/indexing.py
|
|
12
|
+
src/bw_processing/io_helpers.py
|
|
13
|
+
src/bw_processing/io_parquet_helpers.py
|
|
14
|
+
src/bw_processing/io_pyarrow_helpers.py
|
|
15
|
+
src/bw_processing/matrix_entry.py
|
|
16
|
+
src/bw_processing/merging.py
|
|
17
|
+
src/bw_processing/proxies.py
|
|
18
|
+
src/bw_processing/unique_fields.py
|
|
19
|
+
src/bw_processing/utils.py
|
|
20
|
+
src/bw_processing.egg-info/PKG-INFO
|
|
21
|
+
src/bw_processing.egg-info/SOURCES.txt
|
|
22
|
+
src/bw_processing.egg-info/dependency_links.txt
|
|
23
|
+
src/bw_processing.egg-info/requires.txt
|
|
24
|
+
src/bw_processing.egg-info/top_level.txt
|
|
25
|
+
src/bw_processing/examples/__init__.py
|
|
26
|
+
src/bw_processing/examples/datapackage_2.zip
|
|
27
|
+
src/bw_processing/examples/interfaces.py
|
|
28
|
+
src/bw_processing/examples/parquet_files.py
|
|
29
|
+
src/bw_processing/examples/simple.zip
|
|
30
|
+
src/bw_processing/examples/datapackage_1/another name.indices.parquet
|
|
31
|
+
src/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.data.parquet
|
|
32
|
+
src/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.distributions.parquet
|
|
33
|
+
src/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.flip.parquet
|
|
34
|
+
src/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.indices.parquet
|
|
35
|
+
src/bw_processing/examples/datapackage_1/some name.data.parquet
|
|
36
|
+
src/bw_processing/examples/datapackage_1/some name.flip.parquet
|
|
37
|
+
src/bw_processing/examples/datapackage_1/some name.indices.parquet
|
|
38
|
+
tests/test_array_creation.py
|
|
39
|
+
tests/test_datapackage.py
|
|
40
|
+
tests/test_filesystem.py
|
|
41
|
+
tests/test_filtered_datapackage.py
|
|
42
|
+
tests/test_indexing.py
|
|
43
|
+
tests/test_integration.py
|
|
44
|
+
tests/test_interfaces.py
|
|
45
|
+
tests/test_io_parquet_helpers.py
|
|
46
|
+
tests/test_io_pyarrow_helpers.py
|
|
47
|
+
tests/test_loading.py
|
|
48
|
+
tests/test_matrix_entry.py
|
|
49
|
+
tests/test_merging.py
|
|
50
|
+
tests/test_proxies.py
|
|
51
|
+
tests/test_unique_fields.py
|
|
52
|
+
tests/test_utils.py
|