Skip to content

Commit f9f4c73

Browse files
benbovydcherian
andauthored
Fix multiindex level serialization after reset_index (pydata#8672)
* 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>
1 parent ca10531 commit f9f4c73

File tree

3 files changed

+19
-7
lines changed

3 files changed

+19
-7
lines changed

doc/whats-new.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ Deprecations
4343
Bug fixes
4444
~~~~~~~~~
4545

46+
- Fixed a regression that prevented multi-index level coordinates being
47+
serialized after resetting or dropping the multi-index (:issue:`8628`, :pull:`8672`).
48+
By `Benoit Bovy <https://github.com/benbovy>`_.
4649
- Fix bug with broadcasting when wrapping array API-compliant classes. (:issue:`8665`, :pull:`8669`)
4750
By `Tom Nicholas <https://github.com/TomNicholas>`_.
4851
- Ensure :py:meth:`DataArray.unstack` works when wrapping array API-compliant classes. (:issue:`8666`, :pull:`8668`)

xarray/conventions.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
)
1717
from xarray.core.pycompat import is_duck_dask_array
1818
from xarray.core.utils import emit_user_level_warning
19-
from xarray.core.variable import Variable
19+
from xarray.core.variable import IndexVariable, Variable
2020

2121
CF_RELATED_DATA = (
2222
"bounds",
@@ -84,13 +84,17 @@ def _infer_dtype(array, name=None):
8484

8585

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

9599

96100
def _copy_with_dtype(data, dtype: np.typing.DTypeLike):

xarray/tests/test_backends.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,6 +1246,11 @@ def test_multiindex_not_implemented(self) -> None:
12461246
with self.roundtrip(ds):
12471247
pass
12481248

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

12501255
class NetCDFBase(CFEncodedBase):
12511256
"""Tests for all netCDF3 and netCDF4 backends."""

0 commit comments

Comments
 (0)