Skip to content

Commit 9b1d23f

Browse files
Merge pull request #453 from Blosc/expand_dims
Extend functionality of expand_dims
2 parents db28770 + 54cf175 commit 9b1d23f

File tree

5 files changed

+40
-14
lines changed

5 files changed

+40
-14
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ else()
5050
include(FetchContent)
5151
FetchContent_Declare(blosc2
5252
GIT_REPOSITORY https://github.com/Blosc/c-blosc2
53-
GIT_TAG 110493ad34c3f9cc8bafd922a85333c0a46afd95 # v2.19.1
53+
GIT_TAG 2d34ddb0b4832b58d68eae042da00c05a76b72fb # v2.19.2dev0
5454
)
5555
FetchContent_MakeAvailable(blosc2)
5656
include_directories("${blosc2_SOURCE_DIR}/include")

examples/ndarray/animated_plot.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
x = blosc2.linspace(0, n_frames, n_frames, dtype=dtype)
3434
y = blosc2.linspace(-4 * np.pi, 4 * np.pi, width, dtype=dtype)
3535
z = blosc2.linspace(-4 * np.pi, 4 * np.pi, height, dtype=dtype)
36-
X = blosc2.expand_dims(blosc2.expand_dims(x, 1), 2) # Shape: (N, 1, 1)
37-
Y = blosc2.expand_dims(blosc2.expand_dims(y, 0), 2) # Shape: (1, N, 1)
38-
Z = blosc2.expand_dims(blosc2.expand_dims(z, 0), 0) # Shape: (1, 1, N)
36+
X = blosc2.expand_dims(x, (1, 2)) # Shape: (N, 1, 1)
37+
Y = blosc2.expand_dims(y, (0, 2)) # Shape: (1, N, 1)
38+
Z = blosc2.expand_dims(z, (0, 1)) # Shape: (1, 1, N)
3939
if not use_blosc2:
4040
# If not using Blosc2, convert to NumPy arrays
4141
# X, Y, Z = np.meshgrid(x, y, z)

src/blosc2/blosc2_ext.pyx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ cdef extern from "b2nd.h":
509509
int b2nd_copy(b2nd_context_t *ctx, b2nd_array_t *src, b2nd_array_t **array)
510510
int b2nd_concatenate(b2nd_context_t *ctx, b2nd_array_t *src1, b2nd_array_t *src2,
511511
int8_t axis, c_bool copy, b2nd_array_t **array)
512-
int b2nd_expand_dims(const b2nd_array_t *array, b2nd_array_t ** view, const int8_t axis)
512+
int b2nd_expand_dims(const b2nd_array_t *array, b2nd_array_t ** view, const c_bool *axis, const uint8_t final_dims)
513513
int b2nd_get_orthogonal_selection(const b2nd_array_t *array, int64_t ** selection,
514514
int64_t *selection_size, void *buffer,
515515
int64_t *buffershape, int64_t buffersize)
@@ -2971,13 +2971,17 @@ def concat(arr1: NDArray, arr2: NDArray, axis: int, **kwargs):
29712971
# Return the first array, which now contains the concatenated data
29722972
return arr1
29732973

2974-
def expand_dims(arr1: NDArray, axis: int):
2974+
def expand_dims(arr1: NDArray, axis_mask: list[bool], final_dims: int) -> blosc2.NDArray:
29752975
"""
29762976
Add new dummy axis to NDArray object at specified dimension.
29772977
"""
29782978
cdef b2nd_array_t *view
2979-
_check_rc(b2nd_expand_dims(arr1.array, &view, axis),
2980-
"Error while concatenating the arrays")
2979+
cdef c_bool mask_[B2ND_MAX_DIM]
2980+
if final_dims > B2ND_MAX_DIM:
2981+
raise ValueError(f"Cannot expand dimensions beyond {B2ND_MAX_DIM} dimensions")
2982+
for i in range(final_dims):
2983+
mask_[i] = axis_mask[i]
2984+
_check_rc(b2nd_expand_dims(arr1.array, &view, mask_, final_dims),"Error while expanding the arrays")
29812985

29822986
return blosc2.NDArray(_schunk=PyCapsule_New(view.sc, <char *> "blosc2_schunk*", NULL),
29832987
_array=PyCapsule_New(view, <char *> "b2nd_array_t*", NULL))

src/blosc2/ndarray.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3730,13 +3730,33 @@ def concatenate(arrays: list[NDArray], /, axis=0, **kwargs: Any) -> NDArray:
37303730

37313731

37323732
def expand_dims(array: NDArray, axis=0) -> NDArray:
3733+
"""
3734+
Expand the shape of an array by adding new axes at the specified positions.
3735+
3736+
Parameters
3737+
----------
3738+
array: :ref:`NDArray`
3739+
The array to be expanded.
3740+
axis: int or list of int, optional
3741+
Position in the expanded axes where the new axis (or axes) is placed. Default is 0.
3742+
3743+
Returns
3744+
-------
3745+
out: :ref:`NDArray`
3746+
A new NDArray with the expanded shape.
3747+
"""
37333748
if not isinstance(array, blosc2.NDArray):
37343749
raise TypeError("Argument array must be instance of blosc2.NDArray")
3735-
if axis < 0:
3736-
axis += array.ndim + 1 # Adjust axis to be within the new stacked array's dimensions
3737-
if axis > array.ndim:
3738-
raise ValueError(f"Axis {axis} is out of bounds for expanded array of dimension {array.ndim + 1}.")
3739-
return blosc2_ext.expand_dims(array, axis=axis)
3750+
axis = [axis] if isinstance(axis, int) else axis
3751+
final_dims = array.ndim + len(axis)
3752+
mask = [False for i in range(final_dims)]
3753+
for a in axis:
3754+
if a < 0:
3755+
a += final_dims # Adjust axis to be within the new stacked array's dimensions
3756+
if mask[a]:
3757+
raise ValueError("Axis values must be unique.")
3758+
mask[a] = True
3759+
return blosc2_ext.expand_dims(array, axis_mask=mask, final_dims=final_dims)
37403760

37413761

37423762
def stack(arrays: list[NDArray], axis=0, **kwargs: Any) -> NDArray:

tests/ndarray/test_resize.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def test_resize(shape, new_shape, chunks, blocks, fill_value):
3737
((0,), 1, (0,), (0,), 1),
3838
((100, 1230), 1, (200, 100), (55, 3), b"0123"),
3939
((23, 34), 0, (20, 20), (10, 10), 1234),
40-
((80, 51, 60), -1, (20, 10, 33), (6, 6, 26), 3.333),
40+
((80, 51, 60), (-1, -2, 1), (20, 10, 33), (6, 6, 26), 3.333),
4141
],
4242
)
4343
def test_expand_dims(shape, axis, chunks, blocks, fill_value):
@@ -49,6 +49,8 @@ def test_expand_dims(shape, axis, chunks, blocks, fill_value):
4949
np.testing.assert_array_equal(npa, b[:])
5050

5151
# Repeated expansion
52+
axis = (axis,) if isinstance(axis, int) else axis
53+
axis = axis[0] if (len(axis) + b.ndim) > blosc2.MAX_DIM else axis
5254
b = blosc2.expand_dims(b, axis=axis)
5355
npa = np.expand_dims(npa, axis)
5456
assert npa.shape == b.shape

0 commit comments

Comments
 (0)