@@ -43,11 +43,19 @@ def index(x, key):
4343 if n :
4444 where_newaxis [i ] -= n
4545 idx = ndindex .Tuple (* (ia for ia in idx .args if not isinstance (ia , ndindex .Newaxis )))
46- selection = idx .raw
46+ selection = list (idx .raw )
47+
48+ # Use trick from xarray for negative step values
49+ where_negative_step = []
50+ for i , ia in enumerate (idx .args ):
51+ if isinstance (ia , ndindex .Slice ) and ia .step < 0 :
52+ where_negative_step .append (i )
53+ pos_slice = _convert_slice_with_negative_step (selection [i ], x .shape [i ])
54+ selection [i ] = pos_slice
55+ where_negative_step = tuple (where_negative_step )
56+ selection = tuple (selection )
4757
4858 # Check selection is supported
49- if any (ia .step < 1 for ia in idx .args if isinstance (ia , ndindex .Slice )):
50- raise NotImplementedError (f"Slice step must be >= 1: { key } " )
5159 if not all (
5260 isinstance (ia , (ndindex .Integer , ndindex .Slice , ndindex .IntegerArray ))
5361 for ia in idx .args
@@ -140,6 +148,11 @@ def selection_function(out_key):
140148 if chunks != merged_chunks :
141149 out = merge_chunks (out , merged_chunks )
142150
151+ if len (where_negative_step ) > 0 :
152+ from cubed .array_api .manipulation_functions import flip
153+
154+ out = flip (out , axis = where_negative_step )
155+
143156 for axis in where_newaxis :
144157 from cubed .array_api .manipulation_functions import expand_dims
145158
@@ -148,6 +161,16 @@ def selection_function(out_key):
148161 return out
149162
150163
164+ def _convert_slice_with_negative_step (key : slice , size : int ) -> slice :
165+ """Convert a slice with a negative step to one with a positive
166+ step, which must then be followed by a flip.
167+ """
168+ # see https://github.com/pydata/xarray/blob/99ee8c6ca54057a9b994d7685f36236f2d5a69d9/xarray/core/indexing.py#L1056
169+ start , stop , step = key .indices (size )
170+ exact_stop = range (start , stop , step )[- 1 ]
171+ return slice (exact_stop , start + 1 , - step )
172+
173+
151174def _index_num_input_blocks (
152175 idx : ndindex .Tuple , in_chunksizes , out_chunksizes , numblocks
153176):
0 commit comments