|
1 | | -Announcing Python-Blosc2 4.4.2 |
| 1 | +Announcing Python-Blosc2 4.4.3 |
2 | 2 | ============================== |
3 | 3 |
|
4 | | -We are happy to announce this feature and maintenance release that promotes |
5 | | -DSL kernels to first-class CTable computed columns, adds a convenient new |
6 | | -column-assignment API, speeds up bulk NDArray writes, and fixes several |
7 | | -correctness issues. |
| 4 | +We are happy to announce this maintenance release that makes CTable |
| 5 | +cold-start, printing, querying and groupby noticeably faster, trims the |
| 6 | +memory footprint of ``import blosc2``, adds raw-storage access for columns, |
| 7 | +and exposes the new JPEG 2000 codec plugins. |
8 | 8 |
|
9 | 9 | The main highlights are: |
10 | 10 |
|
11 | | -- **DSL kernels as first-class CTable columns**: ``@blosc2.jit``-decorated |
12 | | - functions can now back virtual computed columns, stored generated columns, |
13 | | - and ``where()`` filter predicates directly — in addition to the existing |
14 | | - string-expression form. Columns survive save/open round-trips via |
15 | | - persisted source. |
| 11 | +- **Faster CTable cold-start**: views created by ``select()`` now open |
| 12 | + columns lazily — only the columns actually read are loaded from storage — |
| 13 | + and queries only open the SUMMARY indexes referenced by the predicate, |
| 14 | + instead of every indexed column on a wide persistent table. |
16 | 15 |
|
17 | | -- **New ``t["col"] = arr`` assignment**: a clean shorthand for overwriting all |
18 | | - live rows of a column. Accepts any array-like, including ``blosc2.NDArray``. |
| 16 | +- **Faster printing and groupby**: table rendering now performs a single |
| 17 | + combined sparse read per column (instead of ~6), and groupby takes the |
| 18 | + dense fast path for float key columns whose values are integral and fit a |
| 19 | + compact non-negative range. |
19 | 20 |
|
20 | | -- **Chunked NDArray writes**: passing a ``blosc2.NDArray`` to ``extend()`` or |
21 | | - ``col[:] = arr`` now decompresses one chunk at a time instead of loading |
22 | | - the entire array into memory, keeping peak RSS bounded for large columns. |
| 21 | +- **Lighter imports**: the on-disk chunk prefetcher no longer uses asyncio, |
| 22 | + so ``import blosc2`` skips ~30 asyncio modules and saves ~3 MB of memory. |
| 23 | + A latent prefetcher deadlock on early iterator close was fixed as well. |
23 | 24 |
|
24 | | -- **``BLOSC_ME_JIT`` full override**: the environment variable now takes |
25 | | - unconditional priority over both ``jit=`` and ``jit_backend=`` keyword |
26 | | - arguments, making backend switching from the command line effortless. |
| 25 | +- **New ``Column.raw`` accessor**: the underlying storage container |
| 26 | + (``NDArray``, ``ListArray``, …) as a blosc2-native compressed object — |
| 27 | + unlike ``col[...]`` reads, which always materialize NumPy arrays. Useful |
| 28 | + as a lazy-expression operand and for storage introspection. |
27 | 29 |
|
28 | | -- **Correctness fixes**: a ``None == None`` guard bug that could corrupt rows |
29 | | - when writing to a view-backed column via the NDArray fast path; a missing |
30 | | - view guard in the new ``__setitem__``; and the fast path being silently |
31 | | - disabled for disk-opened tables have all been fixed. |
| 30 | +- **J2K and HTJ2K codecs**: ``blosc2.Codec.J2K`` and ``blosc2.Codec.HTJ2K`` |
| 31 | + expose the IDs for the new JPEG 2000 plugins (``pip install blosc2-j2k`` |
| 32 | + / ``pip install blosc2-htj2k``). Also, C-Blosc2 has been updated to 3.1.3. |
32 | 33 |
|
33 | | -A quick example of the new DSL computed column API:: |
| 34 | +- **Fixes**: ``--float-trunc-prec`` in the ``parquet_to_blosc2`` CLI now |
| 35 | + propagates to nested columns; unsupported computed-column expressions are |
| 36 | + rejected early with an actionable error; and opening a ``.b2z``/``.b2d`` |
| 37 | + store in read mode no longer creates a temporary directory. |
| 38 | + |
| 39 | +A quick example of the new ``Column.raw`` accessor:: |
34 | 40 |
|
35 | 41 | import blosc2 |
36 | 42 | import dataclasses |
37 | | - import numpy as np |
38 | 43 |
|
39 | 44 | @dataclasses.dataclass |
40 | 45 | class Row: |
41 | 46 | price: float = blosc2.field(blosc2.float64()) |
42 | 47 | qty: int = blosc2.field(blosc2.int64()) |
43 | 48 |
|
44 | | - @blosc2.dsl_kernel |
45 | | - def revenue(price, qty): |
46 | | - return price * qty |
47 | | - |
48 | 49 | t = blosc2.CTable(Row, new_data=[(1.5, 10), (2.0, 5), (3.0, 3)]) |
49 | | - t.add_computed_column("revenue", revenue, inputs=["price", "qty"]) |
50 | | - print(t["revenue"][:]) # array([15., 10., 9.]) |
51 | 50 |
|
52 | | - # Column assignment with a blosc2.NDArray — written chunk-by-chunk |
53 | | - new_prices = blosc2.array([1.0, 2.5, 4.0]) |
54 | | - t["price"] = new_prices |
| 51 | + # The raw storage container, as a blosc2-native compressed object. |
| 52 | + # It is over-allocated to chunk capacity, so slice to the live row count. |
| 53 | + raw = t["price"].raw # a blosc2.NDArray |
| 54 | + print(raw[:len(t)]) # [1.5 2. 3. ] |
| 55 | + |
| 56 | + # Usable directly as a lazy-expression operand, without decompressing |
| 57 | + expr = raw * 2.0 |
| 58 | + print(expr[:len(t)]) # [3. 4. 6.] |
55 | 59 |
|
56 | 60 | Install it with:: |
57 | 61 |
|
|
0 commit comments