diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index a15da861cfbec..27d8792797e39 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -388,6 +388,7 @@ Categorical Datetimelike ^^^^^^^^^^^^ - Bug in :class:`Timestamp` constructor failing to raise when ``tz=None`` is explicitly specified in conjunction with timezone-aware ``tzinfo`` or data (:issue:`48688`) +- Bug in :func:`Datafreme.drop` returning ``Freq=None`` when the dataframe has a ``DatetimeIndex`` (:issue:`58743`) - Bug in :func:`date_range` where the last valid timestamp would sometimes not be produced (:issue:`56134`) - Bug in :func:`date_range` where using a negative frequency value would not include all points between the start and end values (:issue:`56382`) - Bug in :func:`tseries.api.guess_datetime_format` would fail to infer time format when "%Y" == "%H%M" (:issue:`57452`) diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 78f04f57029b1..8b05581752ac8 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -48,12 +48,13 @@ from pandas.core.tools.times import to_time if TYPE_CHECKING: - from collections.abc import Hashable + from collections.abc import Hashable, Iterable from pandas._typing import ( Dtype, DtypeObj, Frequency, + IgnoreRaise, IntervalClosedType, Self, TimeAmbiguous, @@ -813,6 +814,18 @@ def indexer_between_time( return mask.nonzero()[0] + # -------------------------------------------------------------------- + + def drop( + self, + labels: Index | np.ndarray | Iterable[Hashable], + errors: IgnoreRaise = "raise", + ) -> DatetimeIndex: + if self.freq is not None: + return Index.drop(self, labels, errors)._with_freq("infer") # type: ignore[attr-defined] + else: + return Index.drop(self, labels, errors) # type: ignore[return-value] + def date_range( start=None, diff --git a/pandas/tests/generic/test_generic.py b/pandas/tests/generic/test_generic.py index 0b607d91baf65..e2b1426fd62bb 100644 --- a/pandas/tests/generic/test_generic.py +++ b/pandas/tests/generic/test_generic.py @@ -483,3 +483,20 @@ def test_flags_identity(self, frame_or_series): assert obj.flags is obj.flags obj2 = obj.copy() assert obj2.flags is not obj.flags + + @pytest.mark.parametrize("freq", ["YE", "ME", "D"]) + def test_drop_method_freq_preservation(self, freq): + # GH 58846 + start = "1970-01-01" + periods = 10 + + index = date_range(start=start, periods=periods, freq=freq) + df = DataFrame((np.ones(len(index))), index=index) + + # set inplace as false + test_df = df.drop(index=df.index[[0, periods - 1]], inplace=False) + tm.assert_equal(test_df.index.freq, index.freq) + + # set inplace as true + df.drop(index=df.index[[0, periods - 1]], inplace=True) + tm.assert_equal(df.index.freq, index.freq) diff --git a/pandas/tests/indexes/datetimes/methods/test_delete.py b/pandas/tests/indexes/datetimes/methods/test_delete.py index 2341499977f22..06822d6bc9004 100644 --- a/pandas/tests/indexes/datetimes/methods/test_delete.py +++ b/pandas/tests/indexes/datetimes/methods/test_delete.py @@ -132,9 +132,8 @@ def test_delete_slice2(self, tz, unit): assert result.freq == expected.freq assert result.tz == expected.tz - # reset freq to None result = ts.drop(ts.index[[1, 3, 5, 7, 9]]).index - expected = dti[::2]._with_freq(None) + expected = dti[::2] tm.assert_index_equal(result, expected) assert result.name == expected.name assert result.freq == expected.freq