Skip to content

Commit

Permalink
Cast PandasIndex to pd.(Multi)Index (pydata#5385)
Browse files Browse the repository at this point in the history
* fastpath cast Xarray's PandasIndex to pd.Index

Also make sure that a multi-index with one unique level are not cast to
a simple pd.Index

* update tests

* [skip-ci] update what's new
  • Loading branch information
benbovy authored May 28, 2021
1 parent 2a3965c commit 2b38adc
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 0 deletions.
3 changes: 3 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ Bug fixes
:py:class:`CFTimeIndex` and upcoming pandas version 1.3.0 (:issue:`5356`,
:pull:`5359`).
By `Spencer Clark <https://github.com/spencerkclark>`_.
- Fix 1-level multi-index incorrectly converted to single index (:issue:`5384`,
:pull:`5385`).
By `Benoit Bovy <https://github.com/benbovy>`_.


Documentation
Expand Down
2 changes: 2 additions & 0 deletions xarray/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ def safe_cast_to_index(array: Any) -> pd.Index:
index = array
elif hasattr(array, "to_index"):
index = array.to_index()
elif hasattr(array, "to_pandas_index"):
index = array.to_pandas_index()
else:
kwargs = {}
if hasattr(array, "dtype") and array.dtype.kind == "O":
Expand Down
3 changes: 3 additions & 0 deletions xarray/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from xarray.coding.cftimeindex import CFTimeIndex
from xarray.core import duck_array_ops, utils
from xarray.core.indexes import PandasIndex
from xarray.core.utils import either_dict_or_kwargs

from . import assert_array_equal, requires_cftime, requires_dask
Expand All @@ -28,11 +29,13 @@ def test_safe_cast_to_index():
dates = pd.date_range("2000-01-01", periods=10)
x = np.arange(5)
td = x * np.timedelta64(1, "D")
midx = pd.MultiIndex.from_tuples([(0,)], names=["a"])
for expected, array in [
(dates, dates.values),
(pd.Index(x, dtype=object), x.astype(object)),
(pd.Index(td), td),
(pd.Index(td, dtype=object), td.astype(object)),
(midx, PandasIndex(midx)),
]:
actual = utils.safe_cast_to_index(array)
assert_array_equal(expected, actual)
Expand Down

0 comments on commit 2b38adc

Please sign in to comment.