Skip to content

Commit

Permalink
Fix multiindex level serialization after reset_index (#8672)
Browse files Browse the repository at this point in the history
* fix serialize multi-index level coord after reset

* add regression test

* update what's new

---------

Co-authored-by: Deepak Cherian <dcherian@users.noreply.github.com>
  • Loading branch information
benbovy and dcherian authored Jan 31, 2024
1 parent ca10531 commit f9f4c73
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 7 deletions.
3 changes: 3 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ Deprecations
Bug fixes
~~~~~~~~~

- Fixed a regression that prevented multi-index level coordinates being
serialized after resetting or dropping the multi-index (:issue:`8628`, :pull:`8672`).
By `Benoit Bovy <https://github.com/benbovy>`_.
- Fix bug with broadcasting when wrapping array API-compliant classes. (:issue:`8665`, :pull:`8669`)
By `Tom Nicholas <https://github.com/TomNicholas>`_.
- Ensure :py:meth:`DataArray.unstack` works when wrapping array API-compliant classes. (:issue:`8666`, :pull:`8668`)
Expand Down
18 changes: 11 additions & 7 deletions xarray/conventions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
)
from xarray.core.pycompat import is_duck_dask_array
from xarray.core.utils import emit_user_level_warning
from xarray.core.variable import Variable
from xarray.core.variable import IndexVariable, Variable

CF_RELATED_DATA = (
"bounds",
Expand Down Expand Up @@ -84,13 +84,17 @@ def _infer_dtype(array, name=None):


def ensure_not_multiindex(var: Variable, name: T_Name = None) -> None:
# only the pandas multi-index dimension coordinate cannot be serialized (tuple values)
if isinstance(var._data, indexing.PandasMultiIndexingAdapter):
raise NotImplementedError(
f"variable {name!r} is a MultiIndex, which cannot yet be "
"serialized. Instead, either use reset_index() "
"to convert MultiIndex levels into coordinate variables instead "
"or use https://cf-xarray.readthedocs.io/en/latest/coding.html."
)
if name is None and isinstance(var, IndexVariable):
name = var.name
if var.dims == (name,):
raise NotImplementedError(
f"variable {name!r} is a MultiIndex, which cannot yet be "
"serialized. Instead, either use reset_index() "
"to convert MultiIndex levels into coordinate variables instead "
"or use https://cf-xarray.readthedocs.io/en/latest/coding.html."
)


def _copy_with_dtype(data, dtype: np.typing.DTypeLike):
Expand Down
5 changes: 5 additions & 0 deletions xarray/tests/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,11 @@ def test_multiindex_not_implemented(self) -> None:
with self.roundtrip(ds):
pass

# regression GH8628 (can serialize reset multi-index level coordinates)
ds_reset = ds.reset_index("x")
with self.roundtrip(ds_reset) as actual:
assert_identical(actual, ds_reset)


class NetCDFBase(CFEncodedBase):
"""Tests for all netCDF3 and netCDF4 backends."""
Expand Down

0 comments on commit f9f4c73

Please sign in to comment.