Skip to content

Commit ad64b75

Browse files
committed
REGR: Index.map adding back tz to tz-agnostic result
1 parent 63dc0f7 commit ad64b75

File tree

3 files changed

+24
-8
lines changed

3 files changed

+24
-8
lines changed

doc/source/whatsnew/v2.2.1.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Fixed regressions
3636
- Fixed regression in :meth:`DataFrameGroupBy.idxmin`, :meth:`DataFrameGroupBy.idxmax`, :meth:`SeriesGroupBy.idxmin`, :meth:`SeriesGroupBy.idxmax` where values containing the minimum or maximum value for the dtype could produce incorrect results (:issue:`57040`)
3737
- Fixed regression in :meth:`ExtensionArray.to_numpy` raising for non-numeric masked dtypes (:issue:`56991`)
3838
- Fixed regression in :meth:`Index.join` raising ``TypeError`` when joining an empty index to a non-empty index containing mixed dtype values (:issue:`57048`)
39+
- Fixed regression in :meth:`Index.map` that would not change the dtype when the provided mapping would change data from tz-aware to tz-agnostic or tz-agnostic to tz-aware (:issue:`57192`)
3940
- Fixed regression in :meth:`Series.pct_change` raising a ``ValueError`` for an empty :class:`Series` (:issue:`57056`)
4041
- Fixed regression in :meth:`Series.to_numpy` when dtype is given as float and the data contains NaNs (:issue:`57121`)
4142

pandas/core/indexes/base.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6124,14 +6124,16 @@ def map(self, mapper, na_action: Literal["ignore"] | None = None):
61246124
# empty
61256125
dtype = self.dtype
61266126

6127-
# e.g. if we are floating and new_values is all ints, then we
6128-
# don't want to cast back to floating. But if we are UInt64
6129-
# and new_values is all ints, we want to try.
6130-
same_dtype = lib.infer_dtype(new_values, skipna=False) == self.inferred_type
6131-
if same_dtype:
6132-
new_values = maybe_cast_pointwise_result(
6133-
new_values, self.dtype, same_dtype=same_dtype
6134-
)
6127+
if self.inferred_type != "datetime64":
6128+
# e.g. if we are floating and new_values is all ints, then we
6129+
# don't want to cast back to floating. But if we are UInt64
6130+
# and new_values is all ints, we want to try.
6131+
# GH#57192 - we skip datetime64 because inference from values is reliable
6132+
same_dtype = lib.infer_dtype(new_values, skipna=False) == self.inferred_type
6133+
if same_dtype:
6134+
new_values = maybe_cast_pointwise_result(
6135+
new_values, self.dtype, same_dtype=same_dtype
6136+
)
61356137

61366138
return Index._with_infer(new_values, dtype=dtype, copy=False, name=self.name)
61376139

pandas/tests/indexes/datetimes/methods/test_map.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,16 @@ def test_index_map(self, name):
4545
)
4646
exp_index = MultiIndex.from_product(((2018,), range(1, 7)), names=[name, name])
4747
tm.assert_index_equal(index, exp_index)
48+
49+
@pytest.mark.parametrize("input_tz", ["UTC", None])
50+
@pytest.mark.parametrize("output_tz", ["UTC", None])
51+
def test_mapping_tz_to_tz_agnostic(self, input_tz, output_tz):
52+
# GH#57192
53+
index = date_range("2018-01-01", periods=6, freq="ME", tz=input_tz)
54+
expected = date_range("2018-01-01", periods=6, freq="ME", tz=output_tz)
55+
if input_tz == "UTC" and output_tz == "UTC":
56+
method = "tz_convert"
57+
else:
58+
method = "tz_localize"
59+
result = index.map(lambda x: getattr(x, method)(output_tz))
60+
tm.assert_index_equal(result, expected)

0 commit comments

Comments
 (0)