bw-processing 1.1__tar.gz → 1.2__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/src/bw_processing.egg-info → bw_processing-1.2}/PKG-INFO +21 -1
- {bw_processing-1.1 → bw_processing-1.2}/README.md +20 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/__init__.py +1 -1
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/io_helpers.py +13 -2
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/matrix_entry.py +16 -0
- {bw_processing-1.1 → bw_processing-1.2/src/bw_processing.egg-info}/PKG-INFO +21 -1
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_datapackage.py +40 -1
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_matrix_entry.py +21 -1
- {bw_processing-1.1 → bw_processing-1.2}/LICENSE +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/MANIFEST.in +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/pyproject.toml +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/setup.cfg +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/array_creation.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/constants.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/datapackage.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/errors.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/__init__.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/datapackage_1/another name.indices.parquet +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.data.parquet +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.distributions.parquet +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.flip.parquet +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/datapackage_1/sa-data-vector-from-dict.indices.parquet +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/datapackage_1/some name.data.parquet +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/datapackage_1/some name.flip.parquet +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/datapackage_1/some name.indices.parquet +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/datapackage_2.zip +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/interfaces.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/parquet_files.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/examples/simple.zip +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/filesystem.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/indexing.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/io_parquet_helpers.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/io_pyarrow_helpers.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/merging.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/proxies.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/unique_fields.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing/utils.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing.egg-info/SOURCES.txt +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing.egg-info/dependency_links.txt +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing.egg-info/requires.txt +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/src/bw_processing.egg-info/top_level.txt +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_array_creation.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_filesystem.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_filtered_datapackage.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_indexing.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_integration.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_interfaces.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_io_parquet_helpers.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_io_pyarrow_helpers.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_loading.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_merging.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_proxies.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_unique_fields.py +0 -0
- {bw_processing-1.1 → bw_processing-1.2}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bw_processing
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2
|
|
4
4
|
Summary: Foo
|
|
5
5
|
Author-email: Chris Mutel <cmutel@gmail.com>
|
|
6
6
|
Maintainer-email: Chris Mutel <cmutel@gmail.com>
|
|
@@ -240,6 +240,26 @@ Datapackages are created using `create_datapackage`, which takes the following a
|
|
|
240
240
|
* overwrite: `bool`, default `False`. Overwrite an existing resource with the same `dirpath` and `name`.
|
|
241
241
|
* compress: `bool`, default `False`. Save to a zipfile, if saving to disk.
|
|
242
242
|
|
|
243
|
+
### Zip file compression
|
|
244
|
+
|
|
245
|
+
When writing a datapackage as a zip file via `generic_zipfile_filesystem`, compression is enabled by default (`zipfile.ZIP_DEFLATED`). Index arrays in particular compress extremely well (often to <10% of their original size) because they contain a limited set of repeated integer values. Float data arrays compress less, but the overall file size reduction is substantial.
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
import zipfile
|
|
249
|
+
from bw_processing.io_helpers import generic_zipfile_filesystem
|
|
250
|
+
|
|
251
|
+
# Default: ZIP_DEFLATED (recommended — good compression, fast)
|
|
252
|
+
fs = generic_zipfile_filesystem(dirpath=some_path, filename="my.zip")
|
|
253
|
+
|
|
254
|
+
# Uncompressed — fastest write/read, largest file
|
|
255
|
+
fs = generic_zipfile_filesystem(dirpath=some_path, filename="my.zip", compression=zipfile.ZIP_STORED)
|
|
256
|
+
|
|
257
|
+
# LZMA — best compression ratio, but much slower to write
|
|
258
|
+
fs = generic_zipfile_filesystem(dirpath=some_path, filename="my.zip", compression=zipfile.ZIP_LZMA)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
The `compression` and `compresslevel` arguments are passed directly to Python's `zipfile.ZipFile`. See the [Python docs](https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile) for all options.
|
|
262
|
+
|
|
243
263
|
Calling this function return an instance of `Datapackage`. You still need to add data.
|
|
244
264
|
|
|
245
265
|
## Contributing
|
|
@@ -198,6 +198,26 @@ Datapackages are created using `create_datapackage`, which takes the following a
|
|
|
198
198
|
* overwrite: `bool`, default `False`. Overwrite an existing resource with the same `dirpath` and `name`.
|
|
199
199
|
* compress: `bool`, default `False`. Save to a zipfile, if saving to disk.
|
|
200
200
|
|
|
201
|
+
### Zip file compression
|
|
202
|
+
|
|
203
|
+
When writing a datapackage as a zip file via `generic_zipfile_filesystem`, compression is enabled by default (`zipfile.ZIP_DEFLATED`). Index arrays in particular compress extremely well (often to <10% of their original size) because they contain a limited set of repeated integer values. Float data arrays compress less, but the overall file size reduction is substantial.
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
import zipfile
|
|
207
|
+
from bw_processing.io_helpers import generic_zipfile_filesystem
|
|
208
|
+
|
|
209
|
+
# Default: ZIP_DEFLATED (recommended — good compression, fast)
|
|
210
|
+
fs = generic_zipfile_filesystem(dirpath=some_path, filename="my.zip")
|
|
211
|
+
|
|
212
|
+
# Uncompressed — fastest write/read, largest file
|
|
213
|
+
fs = generic_zipfile_filesystem(dirpath=some_path, filename="my.zip", compression=zipfile.ZIP_STORED)
|
|
214
|
+
|
|
215
|
+
# LZMA — best compression ratio, but much slower to write
|
|
216
|
+
fs = generic_zipfile_filesystem(dirpath=some_path, filename="my.zip", compression=zipfile.ZIP_LZMA)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The `compression` and `compresslevel` arguments are passed directly to Python's `zipfile.ZipFile`. See the [Python docs](https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile) for all options.
|
|
220
|
+
|
|
201
221
|
Calling this function return an instance of `Datapackage`. You still need to add data.
|
|
202
222
|
|
|
203
223
|
## Contributing
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import json
|
|
2
|
+
import zipfile
|
|
2
3
|
from mimetypes import guess_type
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from typing import Any, Optional, Union
|
|
@@ -35,12 +36,22 @@ def generic_directory_filesystem(*, dirpath: Path) -> DirFileSystem:
|
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
def generic_zipfile_filesystem(
|
|
38
|
-
*,
|
|
39
|
+
*,
|
|
40
|
+
dirpath: Path,
|
|
41
|
+
filename: str,
|
|
42
|
+
write: bool = True,
|
|
43
|
+
compression: int = zipfile.ZIP_DEFLATED,
|
|
44
|
+
compresslevel: Optional[int] = None,
|
|
39
45
|
) -> ZipFileSystem:
|
|
40
46
|
assert isinstance(dirpath, Path), "`dirpath` must be a `pathlib.Path` instance"
|
|
41
47
|
if not dirpath.is_dir():
|
|
42
48
|
raise ValueError("Destination directory `{}` doesn't exist".format(dirpath))
|
|
43
|
-
return ZipFileSystem(
|
|
49
|
+
return ZipFileSystem(
|
|
50
|
+
dirpath / filename,
|
|
51
|
+
mode="w" if write else "r",
|
|
52
|
+
compression=compression,
|
|
53
|
+
compresslevel=compresslevel,
|
|
54
|
+
)
|
|
44
55
|
|
|
45
56
|
|
|
46
57
|
def file_reader(
|
|
@@ -2,6 +2,12 @@ import dataclasses
|
|
|
2
2
|
import math
|
|
3
3
|
from enum import Enum
|
|
4
4
|
|
|
5
|
+
try:
|
|
6
|
+
from stats_arrays import NoUncertainty, UndefinedUncertainty
|
|
7
|
+
_NO_UNCERTAINTY_IDS = (UndefinedUncertainty.id, NoUncertainty.id)
|
|
8
|
+
except ImportError:
|
|
9
|
+
_NO_UNCERTAINTY_IDS = (0, 1)
|
|
10
|
+
|
|
5
11
|
|
|
6
12
|
class MatrixName(str, Enum):
|
|
7
13
|
"""Standard matrix names used in Brightway.
|
|
@@ -63,6 +69,16 @@ class MatrixEntry:
|
|
|
63
69
|
maximum: float = math.nan
|
|
64
70
|
negative: bool = False
|
|
65
71
|
|
|
72
|
+
def __post_init__(self):
|
|
73
|
+
if self.uncertainty_type in _NO_UNCERTAINTY_IDS:
|
|
74
|
+
if math.isnan(self.loc):
|
|
75
|
+
object.__setattr__(self, "loc", self.amount)
|
|
76
|
+
elif self.loc != self.amount:
|
|
77
|
+
raise ValueError(
|
|
78
|
+
f"uncertainty_type {self.uncertainty_type} requires loc == amount, "
|
|
79
|
+
f"got loc={self.loc} but amount={self.amount}"
|
|
80
|
+
)
|
|
81
|
+
|
|
66
82
|
def as_dict(self) -> dict:
|
|
67
83
|
return dataclasses.asdict(self)
|
|
68
84
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bw_processing
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2
|
|
4
4
|
Summary: Foo
|
|
5
5
|
Author-email: Chris Mutel <cmutel@gmail.com>
|
|
6
6
|
Maintainer-email: Chris Mutel <cmutel@gmail.com>
|
|
@@ -240,6 +240,26 @@ Datapackages are created using `create_datapackage`, which takes the following a
|
|
|
240
240
|
* overwrite: `bool`, default `False`. Overwrite an existing resource with the same `dirpath` and `name`.
|
|
241
241
|
* compress: `bool`, default `False`. Save to a zipfile, if saving to disk.
|
|
242
242
|
|
|
243
|
+
### Zip file compression
|
|
244
|
+
|
|
245
|
+
When writing a datapackage as a zip file via `generic_zipfile_filesystem`, compression is enabled by default (`zipfile.ZIP_DEFLATED`). Index arrays in particular compress extremely well (often to <10% of their original size) because they contain a limited set of repeated integer values. Float data arrays compress less, but the overall file size reduction is substantial.
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
import zipfile
|
|
249
|
+
from bw_processing.io_helpers import generic_zipfile_filesystem
|
|
250
|
+
|
|
251
|
+
# Default: ZIP_DEFLATED (recommended — good compression, fast)
|
|
252
|
+
fs = generic_zipfile_filesystem(dirpath=some_path, filename="my.zip")
|
|
253
|
+
|
|
254
|
+
# Uncompressed — fastest write/read, largest file
|
|
255
|
+
fs = generic_zipfile_filesystem(dirpath=some_path, filename="my.zip", compression=zipfile.ZIP_STORED)
|
|
256
|
+
|
|
257
|
+
# LZMA — best compression ratio, but much slower to write
|
|
258
|
+
fs = generic_zipfile_filesystem(dirpath=some_path, filename="my.zip", compression=zipfile.ZIP_LZMA)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
The `compression` and `compresslevel` arguments are passed directly to Python's `zipfile.ZipFile`. See the [Python docs](https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile) for all options.
|
|
262
|
+
|
|
243
263
|
Calling this function return an instance of `Datapackage`. You still need to add data.
|
|
244
264
|
|
|
245
265
|
## Contributing
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import shutil
|
|
2
|
+
import zipfile
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
|
|
4
5
|
import numpy as np
|
|
@@ -10,7 +11,7 @@ from morefs.dict import DictFS
|
|
|
10
11
|
from bw_processing import create_datapackage, load_datapackage, simple_graph
|
|
11
12
|
from bw_processing.constants import INDICES_DTYPE, UNCERTAINTY_DTYPE, MAX_SIGNED_64BIT_INT, MAX_SIGNED_32BIT_INT
|
|
12
13
|
from bw_processing.errors import NonUnique, PotentialInconsistency, ShapeMismatch, WrongDatatype
|
|
13
|
-
from bw_processing.io_helpers import generic_directory_filesystem
|
|
14
|
+
from bw_processing.io_helpers import generic_directory_filesystem, generic_zipfile_filesystem
|
|
14
15
|
|
|
15
16
|
dirpath = Path(__file__).parent.resolve() / "fixtures"
|
|
16
17
|
|
|
@@ -497,3 +498,41 @@ def test_simple_graph():
|
|
|
497
498
|
assert d["col"].sum() == 1102
|
|
498
499
|
d, _ = dp.get_resource("a different life-data.data")
|
|
499
500
|
assert np.allclose(d, np.array([101.234, 777]))
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
def _write_zip_datapackage(dirpath, filename="test.zip", **kwargs):
|
|
504
|
+
fs = generic_zipfile_filesystem(dirpath=dirpath, filename=filename, **kwargs)
|
|
505
|
+
dp = create_datapackage(fs=fs, name="test-zip-compression")
|
|
506
|
+
add_data(dp)
|
|
507
|
+
dp.finalize_serialization()
|
|
508
|
+
return dirpath / filename
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
def test_zipfile_default_compression(tmp_path):
|
|
512
|
+
"""Default compression is ZIP_DEFLATED; indices compress well so file is smaller than uncompressed."""
|
|
513
|
+
compressed_path = _write_zip_datapackage(tmp_path, filename="compressed.zip")
|
|
514
|
+
uncompressed_path = _write_zip_datapackage(tmp_path, filename="uncompressed.zip", compression=zipfile.ZIP_STORED)
|
|
515
|
+
|
|
516
|
+
with zipfile.ZipFile(compressed_path) as zf:
|
|
517
|
+
for info in zf.infolist():
|
|
518
|
+
if info.filename.endswith(".indices.npy"):
|
|
519
|
+
assert info.compress_type == zipfile.ZIP_DEFLATED
|
|
520
|
+
|
|
521
|
+
assert compressed_path.stat().st_size < uncompressed_path.stat().st_size
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
def test_zipfile_stored_compression(tmp_path):
|
|
525
|
+
"""ZIP_STORED writes uncompressed entries."""
|
|
526
|
+
zip_path = _write_zip_datapackage(tmp_path, compression=zipfile.ZIP_STORED)
|
|
527
|
+
|
|
528
|
+
with zipfile.ZipFile(zip_path) as zf:
|
|
529
|
+
for info in zf.infolist():
|
|
530
|
+
assert info.compress_type == zipfile.ZIP_STORED
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
def test_zipfile_compressed_roundtrip(tmp_path):
|
|
534
|
+
"""Data written with ZIP_DEFLATED can be read back correctly."""
|
|
535
|
+
zip_path = _write_zip_datapackage(tmp_path)
|
|
536
|
+
dp = load_datapackage(ZipFileSystem(str(zip_path)))
|
|
537
|
+
data, _ = dp.get_resource("sa-data-vector.data")
|
|
538
|
+
assert np.allclose(data, [2, 7, 12])
|
|
@@ -42,12 +42,32 @@ class TestMatrixEntry:
|
|
|
42
42
|
assert e.flip is False
|
|
43
43
|
assert e.uncertainty_type == 0
|
|
44
44
|
assert e.negative is False
|
|
45
|
-
assert
|
|
45
|
+
assert e.loc == pytest.approx(3.0)
|
|
46
46
|
assert math.isnan(e.scale)
|
|
47
47
|
assert math.isnan(e.shape)
|
|
48
48
|
assert math.isnan(e.minimum)
|
|
49
49
|
assert math.isnan(e.maximum)
|
|
50
50
|
|
|
51
|
+
def test_loc_set_to_amount_for_no_uncertainty(self):
|
|
52
|
+
e = MatrixEntry(row=1, col=2, amount=5.0)
|
|
53
|
+
assert e.loc == pytest.approx(5.0)
|
|
54
|
+
|
|
55
|
+
def test_explicit_loc_matching_amount_accepted(self):
|
|
56
|
+
e = MatrixEntry(row=1, col=2, amount=5.0, uncertainty_type=0, loc=5.0)
|
|
57
|
+
assert e.loc == pytest.approx(5.0)
|
|
58
|
+
|
|
59
|
+
def test_loc_mismatch_raises_for_uncertainty_type_0(self):
|
|
60
|
+
with pytest.raises(ValueError, match="loc == amount"):
|
|
61
|
+
MatrixEntry(row=1, col=2, amount=5.0, uncertainty_type=0, loc=9.9)
|
|
62
|
+
|
|
63
|
+
def test_loc_mismatch_raises_for_uncertainty_type_1(self):
|
|
64
|
+
with pytest.raises(ValueError, match="loc == amount"):
|
|
65
|
+
MatrixEntry(row=1, col=2, amount=5.0, uncertainty_type=1, loc=9.9)
|
|
66
|
+
|
|
67
|
+
def test_loc_not_set_when_uncertainty_type_nonzero(self):
|
|
68
|
+
e = MatrixEntry(row=1, col=2, amount=5.0, uncertainty_type=2)
|
|
69
|
+
assert math.isnan(e.loc)
|
|
70
|
+
|
|
51
71
|
def test_frozen(self):
|
|
52
72
|
e = MatrixEntry(row=1, col=2, amount=3.0)
|
|
53
73
|
with pytest.raises(Exception):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|