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.
Files changed (63) hide show
  1. bw_processing-1.1/MANIFEST.in +3 -0
  2. {bw_processing-0.9.6/bw_processing.egg-info → bw_processing-1.1}/PKG-INFO +4 -3
  3. {bw_processing-0.9.6 → bw_processing-1.1}/README.md +1 -1
  4. {bw_processing-0.9.6 → bw_processing-1.1}/pyproject.toml +3 -1
  5. bw_processing-1.1/src/bw_processing/__init__.py +52 -0
  6. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/constants.py +2 -1
  7. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/datapackage.py +53 -7
  8. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/indexing.py +2 -2
  9. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/io_helpers.py +4 -4
  10. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/io_parquet_helpers.py +2 -2
  11. bw_processing-1.1/src/bw_processing/matrix_entry.py +112 -0
  12. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/merging.py +3 -3
  13. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/unique_fields.py +1 -1
  14. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/utils.py +3 -3
  15. {bw_processing-0.9.6 → bw_processing-1.1/src/bw_processing.egg-info}/PKG-INFO +4 -3
  16. bw_processing-1.1/src/bw_processing.egg-info/SOURCES.txt +52 -0
  17. bw_processing-1.1/tests/test_array_creation.py +14 -0
  18. bw_processing-1.1/tests/test_datapackage.py +499 -0
  19. bw_processing-1.1/tests/test_filesystem.py +33 -0
  20. bw_processing-1.1/tests/test_filtered_datapackage.py +151 -0
  21. bw_processing-1.1/tests/test_indexing.py +384 -0
  22. bw_processing-1.1/tests/test_integration.py +472 -0
  23. bw_processing-1.1/tests/test_interfaces.py +113 -0
  24. bw_processing-1.1/tests/test_io_parquet_helpers.py +138 -0
  25. bw_processing-1.1/tests/test_io_pyarrow_helpers.py +66 -0
  26. bw_processing-1.1/tests/test_loading.py +64 -0
  27. bw_processing-1.1/tests/test_matrix_entry.py +158 -0
  28. bw_processing-1.1/tests/test_merging.py +369 -0
  29. bw_processing-1.1/tests/test_proxies.py +27 -0
  30. bw_processing-1.1/tests/test_unique_fields.py +139 -0
  31. bw_processing-0.9.6/MANIFEST.in +0 -3
  32. bw_processing-0.9.6/bw_processing/__init__.py +0 -48
  33. bw_processing-0.9.6/bw_processing.egg-info/SOURCES.txt +0 -57
  34. bw_processing-0.9.6/dev/calculation_package.py +0 -179
  35. bw_processing-0.9.6/dev/loading.py +0 -85
  36. bw_processing-0.9.6/dev/processed_package.py +0 -261
  37. bw_processing-0.9.6/dev/resources.py +0 -32
  38. bw_processing-0.9.6/dev/speed_tests.py +0 -47
  39. bw_processing-0.9.6/docs/conf.py +0 -109
  40. {bw_processing-0.9.6 → bw_processing-1.1}/LICENSE +0 -0
  41. {bw_processing-0.9.6 → bw_processing-1.1}/setup.cfg +0 -0
  42. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/array_creation.py +0 -0
  43. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/errors.py +0 -0
  44. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/__init__.py +0 -0
  45. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/another name.indices.parquet +0 -0
  46. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.data.parquet +0 -0
  47. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.distributions.parquet +0 -0
  48. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.flip.parquet +0 -0
  49. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.indices.parquet +0 -0
  50. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/some name.data.parquet +0 -0
  51. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/some name.flip.parquet +0 -0
  52. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_1/some name.indices.parquet +0 -0
  53. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/datapackage_2.zip +0 -0
  54. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/interfaces.py +0 -0
  55. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/parquet_files.py +0 -0
  56. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/examples/simple.zip +0 -0
  57. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/filesystem.py +0 -0
  58. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/io_pyarrow_helpers.py +0 -0
  59. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing/proxies.py +0 -0
  60. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing.egg-info/dependency_links.txt +0 -0
  61. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing.egg-info/requires.txt +0 -0
  62. {bw_processing-0.9.6 → bw_processing-1.1/src}/bw_processing.egg-info/top_level.txt +0 -0
  63. {bw_processing-0.9.6 → bw_processing-1.1}/tests/test_utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ include src/bw_processing/examples/*.zip
2
+ include src/bw_processing/examples/datapackage_1/*.parquet
3
+ recursive-exclude dev *
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: bw_processing
3
- Version: 0.9.6
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 [PyFilesystem2](https://docs.pyfilesystem.org/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
+ * **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 [PyFilesystem2](https://docs.pyfilesystem.org/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).
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
- packages = ["bw_processing", "bw_processing.examples"]
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.int32), ("col", np.int32)]
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:
@@ -1,6 +1,6 @@
1
1
  import pandas as pd
2
2
 
3
- from .errors import InconsistentFields, NonUnique
3
+ from bw_processing.errors import InconsistentFields, NonUnique
4
4
 
5
5
 
6
6
  def greedy_set_cover(data, exclude=None, raise_error=True):
@@ -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
1
+ Metadata-Version: 2.4
2
2
  Name: bw_processing
3
- Version: 0.9.6
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 [PyFilesystem2](https://docs.pyfilesystem.org/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
+ * **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
@@ -0,0 +1,14 @@
1
+ from bw_processing.array_creation import chunked
2
+
3
+
4
+ def test_chunked():
5
+ c = chunked(range(600), 250)
6
+ for x in next(c):
7
+ pass
8
+ assert x == 249
9
+ for x in next(c):
10
+ pass
11
+ assert x == 499
12
+ for x in next(c):
13
+ pass
14
+ assert x == 599