@@ -981,19 +981,26 @@ def __iter__(self) -> Iterator[ChunkProjection]:
981981
982982 # handle advanced indexing arrays orthogonally
983983 if self .is_advanced :
984- # N.B., numpy doesn't support orthogonal indexing directly as yet,
985- # so need to work around via np.ix_. Also np.ix_ does not support a
986- # mixture of arrays and slices or integers, so need to convert slices
987- # and integers into ranges.
988- chunk_shape = tuple (
989- g .chunk_size (p .dim_chunk_ix )
990- for g , p in zip (self .dim_grids , dim_projections , strict = True )
991- )
992- chunk_selection = ix_ (chunk_selection , chunk_shape )
984+ # NumPy can handle a single array-indexed dimension directly,
985+ # which preserves full slices and avoids an
986+ # unnecessary advanced-indexing copy. Integer-indexed
987+ # dimensions still need the ix_ path for downstream squeezing.
988+ # Example: we skip `ix_` for array[:, :, [1, 2, 3]]
989+ n_array_dims = sum (isinstance (sel , np .ndarray ) for sel in chunk_selection )
990+
991+ if n_array_dims > 1 or self .drop_axes :
992+ # N.B., numpy doesn't support orthogonal indexing directly
993+ # for multiple array-indexed dimensions, so we need to
994+ # convert the orthogonal selection into coordinate arrays.
995+ chunk_shape = tuple (
996+ g .chunk_size (p .dim_chunk_ix )
997+ for g , p in zip (self .dim_grids , dim_projections , strict = True )
998+ )
999+ chunk_selection = ix_ (chunk_selection , chunk_shape )
9931000
994- # special case for non-monotonic indices
995- if not is_basic_selection (out_selection ):
996- out_selection = ix_ (out_selection , self .shape )
1001+ # special case for non-monotonic indices
1002+ if not is_basic_selection (out_selection ):
1003+ out_selection = ix_ (out_selection , self .shape )
9971004
9981005 is_complete_chunk = all (p .is_complete_chunk for p in dim_projections )
9991006 yield ChunkProjection (chunk_coords , chunk_selection , out_selection , is_complete_chunk )
0 commit comments