diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 37cf3af85b9..6debcb5ca0d 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -24,7 +24,8 @@ New Features - Add a ``create_index=True`` parameter to :py:meth:`Dataset.stack` and :py:meth:`DataArray.stack` so that the creation of multi-indexes is optional - (:pull:`5692`). By `Benoît Bovy `_. + (:pull:`5692`). + By `Benoît Bovy `_. - Multi-index levels are now accessible through their own, regular coordinates instead of virtual coordinates (:pull:`5692`). By `Benoît Bovy `_. @@ -33,7 +34,8 @@ Breaking changes ~~~~~~~~~~~~~~~~ - The Dataset and DataArray ``rename*`` methods do not implicitly add or drop - indexes. (:pull:`5692`). By `Benoît Bovy `_. + indexes. (:pull:`5692`). + By `Benoît Bovy `_. - Many arguments like ``keep_attrs``, ``axis``, and ``skipna`` are now keyword only for all reduction operations like ``.mean``. By `Deepak Cherian `_, `Jimmy Westling `_. @@ -47,12 +49,16 @@ Bug fixes - Set ``skipna=None`` for all ``quantile`` methods (e.g. :py:meth:`Dataset.quantile`) and ensure it skips missing values for float dtypes (consistent with other methods). This should - not change the behavior (:pull:`6303`). By `Mathias Hauser `_. + not change the behavior (:pull:`6303`). + By `Mathias Hauser `_. - Many bugs fixed by the explicit indexes refactor, mainly related to multi-index (virtual) coordinates. See the corresponding pull-request on GitHub for more details. (:pull:`5692`). By `Benoît Bovy `_. - Fixed "unhashable type" error trying to read NetCDF file with variable having its 'units' - attribute not ``str`` (e.g. ``numpy.ndarray``) (:issue:`6368`). By `Oleh Khoma `_. + attribute not ``str`` (e.g. ``numpy.ndarray``) (:issue:`6368`). + By `Oleh Khoma `_. +- Allow fancy indexing of duck dask arrays along multiple dimensions. (:pull:`6414`) + By `Justus Magin `_. Documentation ~~~~~~~~~~~~~ @@ -65,7 +71,6 @@ Internal Changes corresponding pull-request on GitHub for more details. (:pull:`5692`). By `Benoît Bovy `_. -.. _whats-new.2022.02.0: .. _whats-new.2022.03.0: v2022.03.0 (2 March 2022) diff --git a/xarray/core/indexing.py b/xarray/core/indexing.py index c797e6652de..c8851788c29 100644 --- a/xarray/core/indexing.py +++ b/xarray/core/indexing.py @@ -25,13 +25,7 @@ from . import duck_array_ops, nputils, utils from .npcompat import DTypeLike -from .pycompat import ( - dask_array_type, - dask_version, - integer_types, - is_duck_dask_array, - sparse_array_type, -) +from .pycompat import dask_version, integer_types, is_duck_dask_array, sparse_array_type from .types import T_Xarray from .utils import either_dict_or_kwargs, get_valid_numpy_dtype @@ -682,7 +676,7 @@ def as_indexable(array): return NumpyIndexingAdapter(array) if isinstance(array, pd.Index): return PandasIndexingAdapter(array) - if isinstance(array, dask_array_type): + if is_duck_dask_array(array): return DaskIndexingAdapter(array) if hasattr(array, "__array_function__"): return NdArrayLikeIndexingAdapter(array) diff --git a/xarray/tests/test_units.py b/xarray/tests/test_units.py index bc3cc367c0e..c18b7d18c04 100644 --- a/xarray/tests/test_units.py +++ b/xarray/tests/test_units.py @@ -31,7 +31,7 @@ # make sure scalars are converted to 0d arrays so quantities can # always be treated like ndarrays -unit_registry = pint.UnitRegistry(force_ndarray=True) +unit_registry = pint.UnitRegistry(force_ndarray_like=True) Quantity = unit_registry.Quantity @@ -1837,21 +1837,43 @@ def test_broadcast_equals(self, unit, dtype): assert expected == actual + @pytest.mark.parametrize("dask", [False, pytest.param(True, marks=[requires_dask])]) @pytest.mark.parametrize( - "indices", + ["variable", "indexers"], ( - pytest.param(4, id="single index"), - pytest.param([5, 2, 9, 1], id="multiple indices"), + pytest.param( + xr.Variable("x", np.linspace(0, 5, 10)), + {"x": 4}, + id="single value-single indexer", + ), + pytest.param( + xr.Variable("x", np.linspace(0, 5, 10)), + {"x": [5, 2, 9, 1]}, + id="multiple values-single indexer", + ), + pytest.param( + xr.Variable(("x", "y"), np.linspace(0, 5, 20).reshape(4, 5)), + {"x": 1, "y": 4}, + id="single value-multiple indexers", + ), + pytest.param( + xr.Variable(("x", "y"), np.linspace(0, 5, 20).reshape(4, 5)), + {"x": [0, 1, 2], "y": [0, 2, 4]}, + id="multiple values-multiple indexers", + ), ), ) - def test_isel(self, indices, dtype): - array = np.linspace(0, 5, 10).astype(dtype) * unit_registry.s - variable = xr.Variable("x", array) + def test_isel(self, variable, indexers, dask, dtype): + if dask: + variable = variable.chunk({dim: 2 for dim in variable.dims}) + quantified = xr.Variable( + variable.dims, variable.data.astype(dtype) * unit_registry.s + ) expected = attach_units( - strip_units(variable).isel(x=indices), extract_units(variable) + strip_units(quantified).isel(indexers), extract_units(quantified) ) - actual = variable.isel(x=indices) + actual = quantified.isel(indexers) assert_units_equal(expected, actual) assert_identical(expected, actual)