Returns a new chunking aligned with the coarsening multiple. Any excess is at the end of the array. Examples -------- >>> aligned_coarsen_chunks(chunks=(1, 2, 3), multiple=4) (4, 2) >>> aligned_coarsen_chunks(chunks=(1, 20, 3, 4), multiple=4) (4, 20, 4) >>> alig
(chunks: list[int], multiple: int)
| 2322 | |
| 2323 | |
| 2324 | def aligned_coarsen_chunks(chunks: list[int], multiple: int) -> tuple[int, ...]: |
| 2325 | """ |
| 2326 | Returns a new chunking aligned with the coarsening multiple. |
| 2327 | Any excess is at the end of the array. |
| 2328 | |
| 2329 | Examples |
| 2330 | -------- |
| 2331 | >>> aligned_coarsen_chunks(chunks=(1, 2, 3), multiple=4) |
| 2332 | (4, 2) |
| 2333 | >>> aligned_coarsen_chunks(chunks=(1, 20, 3, 4), multiple=4) |
| 2334 | (4, 20, 4) |
| 2335 | >>> aligned_coarsen_chunks(chunks=(20, 10, 15, 23, 24), multiple=10) |
| 2336 | (20, 10, 20, 20, 20, 2) |
| 2337 | """ |
| 2338 | overflow = np.array(chunks) % multiple |
| 2339 | excess = overflow.sum() |
| 2340 | new_chunks = np.array(chunks) - overflow |
| 2341 | # valid chunks are those that are already factorizable by `multiple` |
| 2342 | chunk_validity = new_chunks == chunks |
| 2343 | valid_inds, invalid_inds = np.where(chunk_validity)[0], np.where(~chunk_validity)[0] |
| 2344 | # sort the invalid chunks by size (ascending), then concatenate the results of |
| 2345 | # sorting the valid chunks by size (ascending) |
| 2346 | chunk_modification_order = [ |
| 2347 | *invalid_inds[np.argsort(new_chunks[invalid_inds])], |
| 2348 | *valid_inds[np.argsort(new_chunks[valid_inds])], |
| 2349 | ] |
| 2350 | partitioned_excess, remainder = _partition(excess, multiple) |
| 2351 | # add elements the partitioned excess to the smallest invalid chunks, |
| 2352 | # then smallest valid chunks if needed. |
| 2353 | for idx, extra in enumerate(partitioned_excess): |
| 2354 | new_chunks[chunk_modification_order[idx]] += extra |
| 2355 | # create excess chunk with remainder, if any remainder exists |
| 2356 | new_chunks = np.array([*new_chunks, *remainder]) |
| 2357 | # remove 0-sized chunks |
| 2358 | new_chunks = new_chunks[new_chunks > 0] |
| 2359 | return tuple(new_chunks.tolist()) |
| 2360 | |
| 2361 | |
| 2362 | @wraps(chunk.coarsen) |
no test coverage detected