Skip to content

Commit 68b004f

Browse files
mathausemax-sixty
authored andcommitted
ensure rename does not change index type (#3532)
* ensure rename does not change index type * test requires cftime * test orig.indexes[time].name is conserved * use index.rename()
1 parent aa876cf commit 68b004f

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

doc/whats-new.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ New Features
8383

8484
Bug fixes
8585
~~~~~~~~~
86+
- Ensure an index of type ``CFTimeIndex`` is not converted to a ``DatetimeIndex`` when
87+
calling :py:meth:`Dataset.rename` (also :py:meth:`Dataset.rename_dims`
88+
and :py:meth:`xr.Dataset.rename_vars`). By `Mathias Hauser <https://github.com/mathause>`_
89+
(:issue:`3522`).
8690
- Fix a bug in `set_index` in case that an existing dimension becomes a level variable of MultiIndex. (:pull:`3520`)
8791
By `Keisuke Fujii <https://github.com/fujiisoup>`_.
8892
- Harmonize `_FillValue`, `missing_value` during encoding and decoding steps. (:pull:`3502`)

xarray/core/dataset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2665,7 +2665,7 @@ def _rename_indexes(self, name_dict, dims_set):
26652665
verify_integrity=False,
26662666
)
26672667
else:
2668-
index = pd.Index(v, name=new_name)
2668+
index = v.rename(new_name)
26692669
indexes[new_name] = index
26702670
return indexes
26712671

xarray/tests/test_dataset.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import numpy as np
99
import pandas as pd
1010
import pytest
11+
from pandas.core.indexes.datetimes import DatetimeIndex
1112

1213
import xarray as xr
1314
from xarray import (
@@ -22,6 +23,7 @@
2223
open_dataset,
2324
set_options,
2425
)
26+
from xarray.coding.cftimeindex import CFTimeIndex
2527
from xarray.core import dtypes, indexing, utils
2628
from xarray.core.common import duck_array_ops, full_like
2729
from xarray.core.npcompat import IS_NEP18_ACTIVE
@@ -2458,6 +2460,53 @@ def test_rename_vars(self):
24582460
with pytest.raises(ValueError):
24592461
original.rename_vars(names_dict_bad)
24602462

2463+
@requires_cftime
2464+
def test_rename_does_not_change_CFTimeIndex_type(self):
2465+
# make sure CFTimeIndex is not converted to DatetimeIndex #3522
2466+
2467+
time = xr.cftime_range(start="2000", periods=6, freq="2MS", calendar="noleap")
2468+
orig = Dataset(coords={"time": time})
2469+
2470+
renamed = orig.rename(time="time_new")
2471+
assert "time_new" in renamed.indexes
2472+
assert isinstance(renamed.indexes["time_new"], CFTimeIndex)
2473+
assert renamed.indexes["time_new"].name == "time_new"
2474+
2475+
# check original has not changed
2476+
assert "time" in orig.indexes
2477+
assert isinstance(orig.indexes["time"], CFTimeIndex)
2478+
assert orig.indexes["time"].name == "time"
2479+
2480+
# note: rename_dims(time="time_new") drops "ds.indexes"
2481+
renamed = orig.rename_dims()
2482+
assert isinstance(renamed.indexes["time"], CFTimeIndex)
2483+
2484+
renamed = orig.rename_vars()
2485+
assert isinstance(renamed.indexes["time"], CFTimeIndex)
2486+
2487+
def test_rename_does_not_change_DatetimeIndex_type(self):
2488+
# make sure DatetimeIndex is conderved on rename
2489+
2490+
time = pd.date_range(start="2000", periods=6, freq="2MS")
2491+
orig = Dataset(coords={"time": time})
2492+
2493+
renamed = orig.rename(time="time_new")
2494+
assert "time_new" in renamed.indexes
2495+
assert isinstance(renamed.indexes["time_new"], DatetimeIndex)
2496+
assert renamed.indexes["time_new"].name == "time_new"
2497+
2498+
# check original has not changed
2499+
assert "time" in orig.indexes
2500+
assert isinstance(orig.indexes["time"], DatetimeIndex)
2501+
assert orig.indexes["time"].name == "time"
2502+
2503+
# note: rename_dims(time="time_new") drops "ds.indexes"
2504+
renamed = orig.rename_dims()
2505+
assert isinstance(renamed.indexes["time"], DatetimeIndex)
2506+
2507+
renamed = orig.rename_vars()
2508+
assert isinstance(renamed.indexes["time"], DatetimeIndex)
2509+
24612510
def test_swap_dims(self):
24622511
original = Dataset({"x": [1, 2, 3], "y": ("x", list("abc")), "z": 42})
24632512
expected = Dataset({"z": 42}, {"x": ("y", [1, 2, 3]), "y": list("abc")})

0 commit comments

Comments
 (0)