diff --git a/doc/source/whatsnew/v0.24.0.rst b/doc/source/whatsnew/v0.24.0.rst index 4bc50695e1ecd..eb2c59f6a3519 100644 --- a/doc/source/whatsnew/v0.24.0.rst +++ b/doc/source/whatsnew/v0.24.0.rst @@ -1596,6 +1596,7 @@ Timezones - Bug in :func:`to_datetime` where ``utc=True`` was not respected when passing a :class:`Timestamp` (:issue:`24415`) - Bug in :meth:`DataFrame.any` returns wrong value when ``axis=1`` and the data is of datetimelike type (:issue:`23070`) - Bug in :meth:`DatetimeIndex.to_period` where a timezone aware index was converted to UTC first before creating :class:`PeriodIndex` (:issue:`22905`) +- Bug in :meth:`DataFrame.tz_localize`, :meth:`DataFrame.tz_convert`, :meth:`Series.tz_localize`, and :meth:`Series.tz_convert` where ``copy=False`` would mutate the original argument inplace (:issue:`6326`) Offsets ^^^^^^^ diff --git a/pandas/core/generic.py b/pandas/core/generic.py index d271081aeaa51..1e6ae71660617 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -9226,7 +9226,7 @@ def _tz_convert(ax, tz): ax = _tz_convert(ax, tz) result = self._constructor(self._data, copy=copy) - result.set_axis(ax, axis=axis, inplace=True) + result = result.set_axis(ax, axis=axis, inplace=False) return result.__finalize__(self) def tz_localize(self, tz, axis=0, level=None, copy=True, @@ -9390,7 +9390,7 @@ def _tz_localize(ax, tz, ambiguous, nonexistent): ax = _tz_localize(ax, tz, ambiguous, nonexistent) result = self._constructor(self._data, copy=copy) - result.set_axis(ax, axis=axis, inplace=True) + result = result.set_axis(ax, axis=axis, inplace=False) return result.__finalize__(self) # ---------------------------------------------------------------------- diff --git a/pandas/tests/frame/test_timezones.py b/pandas/tests/frame/test_timezones.py index f124a4c3f3570..fd6587c73b8fa 100644 --- a/pandas/tests/frame/test_timezones.py +++ b/pandas/tests/frame/test_timezones.py @@ -180,3 +180,19 @@ def test_boolean_compare_transpose_tzindex_with_dst(self, tz): result = df.T == df.T expected = DataFrame(True, index=list('ab'), columns=idx) tm.assert_frame_equal(result, expected) + + @pytest.mark.parametrize('copy', [True, False]) + @pytest.mark.parametrize('method, tz', [ + ['tz_localize', None], + ['tz_convert', 'Europe/Berlin'] + ]) + def test_tz_localize_convert_copy_inplace_mutate(self, copy, method, tz): + # GH 6326 + result = DataFrame(np.arange(0, 5), + index=date_range('20131027', periods=5, + freq='1H', tz=tz)) + getattr(result, method)('UTC', copy=copy) + expected = DataFrame(np.arange(0, 5), + index=date_range('20131027', periods=5, + freq='1H', tz=tz)) + tm.assert_frame_equal(result, expected) diff --git a/pandas/tests/series/test_timezones.py b/pandas/tests/series/test_timezones.py index 7f49f94ef57ce..ec644a8e93da2 100644 --- a/pandas/tests/series/test_timezones.py +++ b/pandas/tests/series/test_timezones.py @@ -348,3 +348,19 @@ def test_series_truncate_datetimeindex_tz(self): result = s.truncate(datetime(2005, 4, 2), datetime(2005, 4, 4)) expected = Series([1, 2, 3], index=idx[1:4]) tm.assert_series_equal(result, expected) + + @pytest.mark.parametrize('copy', [True, False]) + @pytest.mark.parametrize('method, tz', [ + ['tz_localize', None], + ['tz_convert', 'Europe/Berlin'] + ]) + def test_tz_localize_convert_copy_inplace_mutate(self, copy, method, tz): + # GH 6326 + result = Series(np.arange(0, 5), + index=date_range('20131027', periods=5, freq='1H', + tz=tz)) + getattr(result, method)('UTC', copy=copy) + expected = Series(np.arange(0, 5), + index=date_range('20131027', periods=5, freq='1H', + tz=tz)) + tm.assert_series_equal(result, expected)