Skip to content

Commit c06a0b5

Browse files
natmokvalpmhatre1
authored andcommitted
CLN: enforce deprecation of the kind keyword on df.resample/ser.resample (pandas-dev#58125)
* enforced deprecation of the kind keyword on df.resample/ser.resample * fix tests * fix tests * fix tests * add a note to v3.0.0 * return a blank line in resample.py back * remove leftover * remove kind from get_resampler, delete test * remove kwd kind from _get_resampler, fix test * remove kwd kind from the class Resampler * remove kind from TimeGrouper * inline the parameter freq in test_resample_5minute
1 parent 420a101 commit c06a0b5

File tree

6 files changed

+67
-168
lines changed

6 files changed

+67
-168
lines changed

doc/source/whatsnew/v3.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ Removal of prior version deprecations/changes
221221
- Disallow units other than "s", "ms", "us", "ns" for datetime64 and timedelta64 dtypes in :func:`array` (:issue:`53817`)
222222
- Removed "freq" keyword from :class:`PeriodArray` constructor, use "dtype" instead (:issue:`52462`)
223223
- Removed 'fastpath' keyword in :class:`Categorical` constructor (:issue:`20110`)
224+
- Removed 'kind' keyword in :meth:`Series.resample` and :meth:`DataFrame.resample` (:issue:`58125`)
224225
- Removed alias :class:`arrays.PandasArray` for :class:`arrays.NumpyExtensionArray` (:issue:`53694`)
225226
- Removed deprecated "method" and "limit" keywords from :meth:`Series.replace` and :meth:`DataFrame.replace` (:issue:`53492`)
226227
- Removed extension test classes ``BaseNoReduceTests``, ``BaseNumericReduceTests``, ``BaseBooleanReduceTests`` (:issue:`54663`)

pandas/core/generic.py

-22
Original file line numberDiff line numberDiff line change
@@ -8662,7 +8662,6 @@ def resample(
86628662
closed: Literal["right", "left"] | None = None,
86638663
label: Literal["right", "left"] | None = None,
86648664
convention: Literal["start", "end", "s", "e"] | lib.NoDefault = lib.no_default,
8665-
kind: Literal["timestamp", "period"] | None | lib.NoDefault = lib.no_default,
86668665
on: Level | None = None,
86678666
level: Level | None = None,
86688667
origin: str | TimestampConvertibleTypes = "start_day",
@@ -8695,14 +8694,6 @@ def resample(
86958694
86968695
.. deprecated:: 2.2.0
86978696
Convert PeriodIndex to DatetimeIndex before resampling instead.
8698-
kind : {{'timestamp', 'period'}}, optional, default None
8699-
Pass 'timestamp' to convert the resulting index to a
8700-
`DateTimeIndex` or 'period' to convert it to a `PeriodIndex`.
8701-
By default the input representation is retained.
8702-
8703-
.. deprecated:: 2.2.0
8704-
Convert index to desired type explicitly instead.
8705-
87068697
on : str, optional
87078698
For a DataFrame, column to use instead of index for resampling.
87088699
Column must be datetime-like.
@@ -8994,18 +8985,6 @@ def resample(
89948985
"""
89958986
from pandas.core.resample import get_resampler
89968987

8997-
if kind is not lib.no_default:
8998-
# GH#55895
8999-
warnings.warn(
9000-
f"The 'kind' keyword in {type(self).__name__}.resample is "
9001-
"deprecated and will be removed in a future version. "
9002-
"Explicitly cast the index to the desired type instead",
9003-
FutureWarning,
9004-
stacklevel=find_stack_level(),
9005-
)
9006-
else:
9007-
kind = None
9008-
90098988
if convention is not lib.no_default:
90108989
warnings.warn(
90118990
f"The 'convention' keyword in {type(self).__name__}.resample is "
@@ -9023,7 +9002,6 @@ def resample(
90239002
freq=rule,
90249003
label=label,
90259004
closed=closed,
9026-
kind=kind,
90279005
convention=convention,
90289006
key=on,
90299007
level=level,

pandas/core/resample.py

+13-31
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,6 @@ class Resampler(BaseGroupBy, PandasObject):
130130
----------
131131
obj : Series or DataFrame
132132
groupby : TimeGrouper
133-
kind : str or None
134-
'period', 'timestamp' to override default index treatment
135133
136134
Returns
137135
-------
@@ -154,7 +152,6 @@ class Resampler(BaseGroupBy, PandasObject):
154152
"closed",
155153
"label",
156154
"convention",
157-
"kind",
158155
"origin",
159156
"offset",
160157
]
@@ -163,7 +160,6 @@ def __init__(
163160
self,
164161
obj: NDFrame,
165162
timegrouper: TimeGrouper,
166-
kind=None,
167163
*,
168164
gpr_index: Index,
169165
group_keys: bool = False,
@@ -173,7 +169,6 @@ def __init__(
173169
self._timegrouper = timegrouper
174170
self.keys = None
175171
self.sort = True
176-
self.kind = kind
177172
self.group_keys = group_keys
178173
self.as_index = True
179174
self.include_groups = include_groups
@@ -1580,7 +1575,7 @@ def _resampler_for_grouping(self) -> type[DatetimeIndexResamplerGroupby]:
15801575

15811576
def _get_binner_for_time(self):
15821577
# this is how we are actually creating the bins
1583-
if self.kind == "period":
1578+
if isinstance(self.ax, PeriodIndex):
15841579
return self._timegrouper._get_time_period_bins(self.ax)
15851580
return self._timegrouper._get_time_bins(self.ax)
15861581

@@ -1678,7 +1673,9 @@ def _wrap_result(self, result):
16781673

16791674
# we may have a different kind that we were asked originally
16801675
# convert if needed
1681-
if self.kind == "period" and not isinstance(result.index, PeriodIndex):
1676+
if isinstance(self.ax, PeriodIndex) and not isinstance(
1677+
result.index, PeriodIndex
1678+
):
16821679
if isinstance(result.index, MultiIndex):
16831680
# GH 24103 - e.g. groupby resample
16841681
if not isinstance(result.index.levels[-1], PeriodIndex):
@@ -1719,7 +1716,7 @@ def _resampler_for_grouping(self):
17191716
return PeriodIndexResamplerGroupby
17201717

17211718
def _get_binner_for_time(self):
1722-
if self.kind == "timestamp":
1719+
if isinstance(self.ax, DatetimeIndex):
17231720
return super()._get_binner_for_time()
17241721
return self._timegrouper._get_period_bins(self.ax)
17251722

@@ -1736,7 +1733,7 @@ def _convert_obj(self, obj: NDFrameT) -> NDFrameT:
17361733
raise NotImplementedError(msg)
17371734

17381735
# convert to timestamp
1739-
if self.kind == "timestamp":
1736+
if isinstance(obj, DatetimeIndex):
17401737
obj = obj.to_timestamp(how=self.convention)
17411738

17421739
return obj
@@ -1751,7 +1748,7 @@ def _downsample(self, how, **kwargs):
17511748
**kwargs : kw args passed to how function
17521749
"""
17531750
# we may need to actually resample as if we are timestamps
1754-
if self.kind == "timestamp":
1751+
if isinstance(self.ax, DatetimeIndex):
17551752
return super()._downsample(how, **kwargs)
17561753

17571754
ax = self.ax
@@ -1788,7 +1785,7 @@ def _upsample(self, method, limit: int | None = None, fill_value=None):
17881785
Value to use for missing values.
17891786
"""
17901787
# we may need to actually resample as if we are timestamps
1791-
if self.kind == "timestamp":
1788+
if isinstance(self.ax, DatetimeIndex):
17921789
return super()._upsample(method, limit=limit, fill_value=fill_value)
17931790

17941791
ax = self.ax
@@ -1860,12 +1857,12 @@ def _resampler_cls(self):
18601857
return TimedeltaIndexResampler
18611858

18621859

1863-
def get_resampler(obj: Series | DataFrame, kind=None, **kwds) -> Resampler:
1860+
def get_resampler(obj: Series | DataFrame, **kwds) -> Resampler:
18641861
"""
18651862
Create a TimeGrouper and return our resampler.
18661863
"""
18671864
tg = TimeGrouper(obj, **kwds) # type: ignore[arg-type]
1868-
return tg._get_resampler(obj, kind=kind)
1865+
return tg._get_resampler(obj)
18691866

18701867

18711868
get_resampler.__doc__ = Resampler.__doc__
@@ -1877,7 +1874,6 @@ def get_resampler_for_grouping(
18771874
how=None,
18781875
fill_method=None,
18791876
limit: int | None = None,
1880-
kind=None,
18811877
on=None,
18821878
include_groups: bool = True,
18831879
**kwargs,
@@ -1887,7 +1883,7 @@ def get_resampler_for_grouping(
18871883
"""
18881884
# .resample uses 'on' similar to how .groupby uses 'key'
18891885
tg = TimeGrouper(freq=rule, key=on, **kwargs)
1890-
resampler = tg._get_resampler(groupby.obj, kind=kind)
1886+
resampler = tg._get_resampler(groupby.obj)
18911887
return resampler._get_resampler_for_grouping(
18921888
groupby=groupby, include_groups=include_groups, key=tg.key
18931889
)
@@ -1910,7 +1906,6 @@ class TimeGrouper(Grouper):
19101906
"closed",
19111907
"label",
19121908
"how",
1913-
"kind",
19141909
"convention",
19151910
"origin",
19161911
"offset",
@@ -1928,7 +1923,6 @@ def __init__(
19281923
how: str = "mean",
19291924
fill_method=None,
19301925
limit: int | None = None,
1931-
kind: str | None = None,
19321926
convention: Literal["start", "end", "e", "s"] | None = None,
19331927
origin: Literal["epoch", "start", "start_day", "end", "end_day"]
19341928
| TimestampConvertibleTypes = "start_day",
@@ -1986,7 +1980,6 @@ def __init__(
19861980

19871981
self.closed = closed
19881982
self.label = label
1989-
self.kind = kind
19901983
self.convention = convention if convention is not None else "e"
19911984
self.how = how
19921985
self.fill_method = fill_method
@@ -2024,15 +2017,13 @@ def __init__(
20242017

20252018
super().__init__(freq=freq, key=key, **kwargs)
20262019

2027-
def _get_resampler(self, obj: NDFrame, kind=None) -> Resampler:
2020+
def _get_resampler(self, obj: NDFrame) -> Resampler:
20282021
"""
20292022
Return my resampler or raise if we have an invalid axis.
20302023
20312024
Parameters
20322025
----------
20332026
obj : Series or DataFrame
2034-
kind : string, optional
2035-
'period','timestamp','timedelta' are valid
20362027
20372028
Returns
20382029
-------
@@ -2048,11 +2039,10 @@ def _get_resampler(self, obj: NDFrame, kind=None) -> Resampler:
20482039
return DatetimeIndexResampler(
20492040
obj,
20502041
timegrouper=self,
2051-
kind=kind,
20522042
group_keys=self.group_keys,
20532043
gpr_index=ax,
20542044
)
2055-
elif isinstance(ax, PeriodIndex) or kind == "period":
2045+
elif isinstance(ax, PeriodIndex):
20562046
if isinstance(ax, PeriodIndex):
20572047
# GH#53481
20582048
warnings.warn(
@@ -2061,17 +2051,9 @@ def _get_resampler(self, obj: NDFrame, kind=None) -> Resampler:
20612051
FutureWarning,
20622052
stacklevel=find_stack_level(),
20632053
)
2064-
else:
2065-
warnings.warn(
2066-
"Resampling with kind='period' is deprecated. "
2067-
"Use datetime paths instead.",
2068-
FutureWarning,
2069-
stacklevel=find_stack_level(),
2070-
)
20712054
return PeriodIndexResampler(
20722055
obj,
20732056
timegrouper=self,
2074-
kind=kind,
20752057
group_keys=self.group_keys,
20762058
gpr_index=ax,
20772059
)

pandas/tests/resample/test_datetime_index.py

+10-36
Original file line numberDiff line numberDiff line change
@@ -441,19 +441,6 @@ def test_resample_frame_basic_M_A(freq, unit):
441441
tm.assert_series_equal(result["A"], df["A"].resample(freq).mean())
442442

443443

444-
@pytest.mark.parametrize("freq", ["W-WED", "ME"])
445-
def test_resample_frame_basic_kind(freq, unit):
446-
df = DataFrame(
447-
np.random.default_rng(2).standard_normal((10, 4)),
448-
columns=Index(list("ABCD"), dtype=object),
449-
index=date_range("2000-01-01", periods=10, freq="B"),
450-
)
451-
df.index = df.index.as_unit(unit)
452-
msg = "The 'kind' keyword in DataFrame.resample is deprecated"
453-
with tm.assert_produces_warning(FutureWarning, match=msg):
454-
df.resample(freq, kind="period").mean()
455-
456-
457444
def test_resample_upsample(unit):
458445
# from daily
459446
dti = date_range(
@@ -665,9 +652,7 @@ def test_resample_timestamp_to_period(
665652
ts = simple_date_range_series("1/1/1990", "1/1/2000")
666653
ts.index = ts.index.as_unit(unit)
667654

668-
msg = "The 'kind' keyword in Series.resample is deprecated"
669-
with tm.assert_produces_warning(FutureWarning, match=msg):
670-
result = ts.resample(freq, kind="period").mean()
655+
result = ts.resample(freq).mean().to_period()
671656
expected = ts.resample(freq).mean()
672657
expected.index = period_range(**expected_kwargs)
673658
tm.assert_series_equal(result, expected)
@@ -985,9 +970,7 @@ def test_resample_to_period_monthly_buglet(unit):
985970
rng = date_range("1/1/2000", "12/31/2000").as_unit(unit)
986971
ts = Series(np.random.default_rng(2).standard_normal(len(rng)), index=rng)
987972

988-
msg = "The 'kind' keyword in Series.resample is deprecated"
989-
with tm.assert_produces_warning(FutureWarning, match=msg):
990-
result = ts.resample("ME", kind="period").mean()
973+
result = ts.resample("ME").mean().to_period()
991974
exp_index = period_range("Jan-2000", "Dec-2000", freq="M")
992975
tm.assert_index_equal(result.index, exp_index)
993976

@@ -1109,18 +1092,15 @@ def test_resample_anchored_intraday(unit):
11091092
df = DataFrame(rng.month, index=rng)
11101093

11111094
result = df.resample("ME").mean()
1112-
msg = "The 'kind' keyword in DataFrame.resample is deprecated"
1113-
with tm.assert_produces_warning(FutureWarning, match=msg):
1114-
expected = df.resample("ME", kind="period").mean().to_timestamp(how="end")
1095+
expected = df.resample("ME").mean().to_period()
1096+
expected = expected.to_timestamp(how="end")
11151097
expected.index += Timedelta(1, "ns") - Timedelta(1, "D")
11161098
expected.index = expected.index.as_unit(unit)._with_freq("infer")
11171099
assert expected.index.freq == "ME"
11181100
tm.assert_frame_equal(result, expected)
11191101

11201102
result = df.resample("ME", closed="left").mean()
1121-
msg = "The 'kind' keyword in DataFrame.resample is deprecated"
1122-
with tm.assert_produces_warning(FutureWarning, match=msg):
1123-
exp = df.shift(1, freq="D").resample("ME", kind="period").mean()
1103+
exp = df.shift(1, freq="D").resample("ME").mean().to_period()
11241104
exp = exp.to_timestamp(how="end")
11251105

11261106
exp.index = exp.index + Timedelta(1, "ns") - Timedelta(1, "D")
@@ -1134,21 +1114,17 @@ def test_resample_anchored_intraday2(unit):
11341114
df = DataFrame(rng.month, index=rng)
11351115

11361116
result = df.resample("QE").mean()
1137-
msg = "The 'kind' keyword in DataFrame.resample is deprecated"
1138-
with tm.assert_produces_warning(FutureWarning, match=msg):
1139-
expected = df.resample("QE", kind="period").mean().to_timestamp(how="end")
1117+
expected = df.resample("QE").mean().to_period()
1118+
expected = expected.to_timestamp(how="end")
11401119
expected.index += Timedelta(1, "ns") - Timedelta(1, "D")
11411120
expected.index._data.freq = "QE"
11421121
expected.index._freq = lib.no_default
11431122
expected.index = expected.index.as_unit(unit)
11441123
tm.assert_frame_equal(result, expected)
11451124

11461125
result = df.resample("QE", closed="left").mean()
1147-
msg = "The 'kind' keyword in DataFrame.resample is deprecated"
1148-
with tm.assert_produces_warning(FutureWarning, match=msg):
1149-
expected = (
1150-
df.shift(1, freq="D").resample("QE", kind="period", closed="left").mean()
1151-
)
1126+
expected = df.shift(1, freq="D").resample("QE").mean()
1127+
expected = expected.to_period()
11521128
expected = expected.to_timestamp(how="end")
11531129
expected.index += Timedelta(1, "ns") - Timedelta(1, "D")
11541130
expected.index._data.freq = "QE"
@@ -1205,9 +1181,7 @@ def test_corner_cases_date(simple_date_range_series, unit):
12051181
# resample to periods
12061182
ts = simple_date_range_series("2000-04-28", "2000-04-30 11:00", freq="h")
12071183
ts.index = ts.index.as_unit(unit)
1208-
msg = "The 'kind' keyword in Series.resample is deprecated"
1209-
with tm.assert_produces_warning(FutureWarning, match=msg):
1210-
result = ts.resample("ME", kind="period").mean()
1184+
result = ts.resample("ME").mean().to_period()
12111185
assert len(result) == 1
12121186
assert result.index[0] == Period("2000-04", freq="M")
12131187

0 commit comments

Comments
 (0)