|
35 | 35 | ArrayOfIntOrBool = npt.NDArray[np.intp] | npt.NDArray[np.bool_]
|
36 | 36 | BasicSelector = int | slice | EllipsisType
|
37 | 37 | Selector = BasicSelector | ArrayOfIntOrBool
|
38 |
| - |
39 | 38 | BasicSelection = BasicSelector | tuple[BasicSelector, ...] # also used for BlockIndex
|
40 | 39 | CoordinateSelection = IntSequence | tuple[IntSequence, ...]
|
41 | 40 | MaskSelection = npt.NDArray[np.bool_]
|
@@ -75,6 +74,15 @@ def err_too_many_indices(selection: Any, shape: ChunkCoords) -> None:
|
75 | 74 | raise IndexError(f"too many indices for array; expected {len(shape)}, got {len(selection)}")
|
76 | 75 |
|
77 | 76 |
|
| 77 | +def _zarr_array_to_int_or_bool_array(arr: Array) -> npt.NDArray[np.intp] | npt.NDArray[np.bool_]: |
| 78 | + if arr.dtype.kind in ("i", "b"): |
| 79 | + return np.asarray(arr) |
| 80 | + else: |
| 81 | + raise IndexError( |
| 82 | + f"Invalid array dtype: {arr.dtype}. Arrays used as indices must be of integer or boolean type" |
| 83 | + ) |
| 84 | + |
| 85 | + |
78 | 86 | @runtime_checkable
|
79 | 87 | class Indexer(Protocol):
|
80 | 88 | shape: ChunkCoords
|
@@ -842,7 +850,14 @@ def __iter__(self) -> Iterator[ChunkProjection]:
|
842 | 850 | class OIndex:
|
843 | 851 | array: Array
|
844 | 852 |
|
845 |
| - def __getitem__(self, selection: OrthogonalSelection) -> NDArrayLike: |
| 853 | + # TODO: develop Array generic and move zarr.Array[np.intp] | zarr.Array[np.bool_] to ArrayOfIntOrBool |
| 854 | + def __getitem__(self, selection: OrthogonalSelection | Array) -> NDArrayLike: |
| 855 | + from zarr.core.array import Array |
| 856 | + |
| 857 | + # if input is a Zarr array, we materialize it now. |
| 858 | + if isinstance(selection, Array): |
| 859 | + selection = _zarr_array_to_int_or_bool_array(selection) |
| 860 | + |
846 | 861 | fields, new_selection = pop_fields(selection)
|
847 | 862 | new_selection = ensure_tuple(new_selection)
|
848 | 863 | new_selection = replace_lists(new_selection)
|
@@ -1130,7 +1145,13 @@ def __init__(self, selection: MaskSelection, shape: ChunkCoords, chunk_grid: Chu
|
1130 | 1145 | class VIndex:
|
1131 | 1146 | array: Array
|
1132 | 1147 |
|
1133 |
| - def __getitem__(self, selection: CoordinateSelection | MaskSelection) -> NDArrayLike: |
| 1148 | + # TODO: develop Array generic and move zarr.Array[np.intp] | zarr.Array[np.bool_] to ArrayOfIntOrBool |
| 1149 | + def __getitem__(self, selection: CoordinateSelection | MaskSelection | Array) -> NDArrayLike: |
| 1150 | + from zarr.core.array import Array |
| 1151 | + |
| 1152 | + # if input is a Zarr array, we materialize it now. |
| 1153 | + if isinstance(selection, Array): |
| 1154 | + selection = _zarr_array_to_int_or_bool_array(selection) |
1134 | 1155 | fields, new_selection = pop_fields(selection)
|
1135 | 1156 | new_selection = ensure_tuple(new_selection)
|
1136 | 1157 | new_selection = replace_lists(new_selection)
|
|
0 commit comments