Skip to content

Commit 4ffe594

Browse files
committed
Added 1D fast path using bincount
1 parent 0883a1c commit 4ffe594

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

src/blosc2/ndarray.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,7 @@ def get_fselection_numpy(self, key: list | np.ndarray) -> np.ndarray: # noqa: C
14851485
chunks = self.chunks
14861486
# after this, all indices are slices or arrays of integers
14871487
# moreover, all arrays are consecutive (otherwise an error is raised)
1488+
# TODO: try to optimise and avoid this expand which seems to copy - maybe np.broadcast
14881489
_slice = ndindex.ndindex(key).expand(shape)
14891490
out_shape = _slice.newshape(shape)
14901491
_slice = _slice.raw
@@ -1522,7 +1523,7 @@ def get_fselection_numpy(self, key: list | np.ndarray) -> np.ndarray: # noqa: C
15221523

15231524
# flush at the end if arrays remain
15241525
if arrs:
1525-
arr = np.stack(arrs)
1526+
arr = np.stack(arrs) # uses quite a bit of memory seemingly
15261527
flat_shape += (arr.shape[-1],)
15271528

15281529
# out_shape could have new dims if indexing arrays are not all 1D
@@ -1531,10 +1532,16 @@ def get_fselection_numpy(self, key: list | np.ndarray) -> np.ndarray: # noqa: C
15311532
post_tuple = _slice[end:] if end is not None else ()
15321533
divider = chunks[begin:end]
15331534
chunked_arr = arr.T // divider
1534-
unique_chunks, chunk_nitems = np.unique(chunked_arr, axis=0, return_counts=True)
15351535
if len(arr) == 1: # 1D chunks, can avoid loading whole chunks
15361536
idx_order = np.argsort(arr.squeeze(axis=0), axis=-1) # sort by real index
1537+
chunk_nitems = np.bincount(
1538+
chunked_arr.reshape(-1), minlength=self.schunk.nchunks
1539+
) # only works for 1D but faster (no copy or sort)
1540+
unique_chunks = np.nonzero(chunk_nitems)
1541+
chunk_nitems = chunk_nitems[unique_chunks]
15371542
else:
1543+
# does a copy and sorts - can this be avoided?
1544+
unique_chunks, chunk_nitems = np.unique(chunked_arr, axis=0, return_counts=True)
15381545
idx_order = np.lexsort(
15391546
tuple(a for a in reversed(chunked_arr.T))
15401547
) # sort by chunks (can't sort by index since larger index could belong to lower chunk)

0 commit comments

Comments
 (0)