diff --git a/doc/whats-new.rst b/doc/whats-new.rst index cd5ecd83978..0b7fc87201b 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -45,6 +45,8 @@ Bug fixes - add a ``keep_attrs`` parameter to :py:meth:`Dataset.pad`, :py:meth:`DataArray.pad`, and :py:meth:`Variable.pad` (:pull:`7267`). By `Justus Magin `_. +- Preserve original dtype on accessing MultiIndex levels (:issue:`7250`, + :pull:`7393`). By `Ian Carroll `_. Documentation ~~~~~~~~~~~~~ diff --git a/xarray/core/indexing.py b/xarray/core/indexing.py index ba937183d24..e49a072df1d 100644 --- a/xarray/core/indexing.py +++ b/xarray/core/indexing.py @@ -1531,8 +1531,12 @@ def __init__( self.level = level def __array__(self, dtype: DTypeLike = None) -> np.ndarray: + if dtype is None: + dtype = self.dtype if self.level is not None: - return self.array.get_level_values(self.level).values + return np.asarray( + self.array.get_level_values(self.level).values, dtype=dtype + ) else: return super().__array__(dtype) diff --git a/xarray/tests/test_indexes.py b/xarray/tests/test_indexes.py index 3ecfa73cc89..caf0f51135e 100644 --- a/xarray/tests/test_indexes.py +++ b/xarray/tests/test_indexes.py @@ -697,3 +697,10 @@ def test_safe_cast_to_index_datetime_datetime(): actual = safe_cast_to_index(np.array(dates)) assert_array_equal(expected, actual) assert isinstance(actual, pd.Index) + + +@pytest.mark.parametrize("dtype", ["int32", "float32"]) +def test_restore_dtype_on_multiindexes(dtype: str) -> None: + foo = xr.Dataset(coords={"bar": ("bar", np.array([0, 1], dtype=dtype))}) + foo = foo.stack(baz=("bar",)) + assert str(foo["bar"].values.dtype) == dtype