Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 96899d7

Browse files
author
tp
committedDec 4, 2017
Remove freq keyword from df.rolling() etc.
1 parent 2c903d5 commit 96899d7

File tree

5 files changed

+63
-131
lines changed

5 files changed

+63
-131
lines changed
 

‎doc/source/whatsnew/v0.22.0.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ Removal of prior version deprecations/changes
150150
- ``pd.tseries.util.isleapyear`` has been removed (deprecated since v0.19). Use ``.is_leap_year`` property in Datetime-likes instead (:issue:`18370`)
151151
- ``pd.ordered_merge`` has been removed (deprecated since v0.19). Use ``pd.merge_ordered`` instead (:issue:`18459`)
152152
- The ``SparseList`` class has been removed (:issue:`14007`)
153+
- The ``freq`` parameter has been removed from the ``rolling``/``expanding``/``ewm`` methods of DataFrame
154+
and Series (deprecated since v0.18). Instead, resample before calling the methods. (:issue:18601)
153155

154156
.. _whatsnew_0220.performance:
155157

‎pandas/core/generic.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7357,31 +7357,31 @@ def _add_series_or_dataframe_operations(cls):
73577357
from pandas.core import window as rwindow
73587358

73597359
@Appender(rwindow.rolling.__doc__)
7360-
def rolling(self, window, min_periods=None, freq=None, center=False,
7360+
def rolling(self, window, min_periods=None, center=False,
73617361
win_type=None, on=None, axis=0, closed=None):
73627362
axis = self._get_axis_number(axis)
73637363
return rwindow.rolling(self, window=window,
7364-
min_periods=min_periods, freq=freq,
7364+
min_periods=min_periods,
73657365
center=center, win_type=win_type,
73667366
on=on, axis=axis, closed=closed)
73677367

73687368
cls.rolling = rolling
73697369

73707370
@Appender(rwindow.expanding.__doc__)
7371-
def expanding(self, min_periods=1, freq=None, center=False, axis=0):
7371+
def expanding(self, min_periods=1, center=False, axis=0):
73727372
axis = self._get_axis_number(axis)
7373-
return rwindow.expanding(self, min_periods=min_periods, freq=freq,
7373+
return rwindow.expanding(self, min_periods=min_periods,
73747374
center=center, axis=axis)
73757375

73767376
cls.expanding = expanding
73777377

73787378
@Appender(rwindow.ewm.__doc__)
73797379
def ewm(self, com=None, span=None, halflife=None, alpha=None,
7380-
min_periods=0, freq=None, adjust=True, ignore_na=False,
7380+
min_periods=0, adjust=True, ignore_na=False,
73817381
axis=0):
73827382
axis = self._get_axis_number(axis)
73837383
return rwindow.ewm(self, com=com, span=span, halflife=halflife,
7384-
alpha=alpha, min_periods=min_periods, freq=freq,
7384+
alpha=alpha, min_periods=min_periods,
73857385
adjust=adjust, ignore_na=ignore_na, axis=axis)
73867386

73877387
cls.ewm = ewm

‎pandas/core/window.py

Lines changed: 26 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -58,27 +58,21 @@
5858

5959

6060
class _Window(PandasObject, SelectionMixin):
61-
_attributes = ['window', 'min_periods', 'freq', 'center', 'win_type',
61+
_attributes = ['window', 'min_periods', 'center', 'win_type',
6262
'axis', 'on', 'closed']
6363
exclusions = set()
6464

65-
def __init__(self, obj, window=None, min_periods=None, freq=None,
65+
def __init__(self, obj, window=None, min_periods=None,
6666
center=False, win_type=None, axis=0, on=None, closed=None,
6767
**kwargs):
6868

69-
if freq is not None:
70-
warnings.warn("The freq kw is deprecated and will be removed in a "
71-
"future version. You can resample prior to passing "
72-
"to a window function", FutureWarning, stacklevel=3)
73-
7469
self.__dict__.update(kwargs)
7570
self.blocks = []
7671
self.obj = obj
7772
self.on = on
7873
self.closed = closed
7974
self.window = window
8075
self.min_periods = min_periods
81-
self.freq = freq
8276
self.center = center
8377
self.win_type = win_type
8478
self.win_freq = None
@@ -117,16 +111,6 @@ def _convert_freq(self, how=None):
117111

118112
obj = self._selected_obj
119113
index = None
120-
if (self.freq is not None and
121-
isinstance(obj, (ABCSeries, ABCDataFrame))):
122-
if how is not None:
123-
warnings.warn("The how kw argument is deprecated and removed "
124-
"in a future version. You can resample prior "
125-
"to passing to a window function", FutureWarning,
126-
stacklevel=6)
127-
128-
obj = obj.resample(self.freq).aggregate(how or 'asfreq')
129-
130114
return obj, index
131115

132116
def _create_blocks(self, how):
@@ -374,14 +358,11 @@ class Window(_Window):
374358
Minimum number of observations in window required to have a value
375359
(otherwise result is NA). For a window that is specified by an offset,
376360
this will default to 1.
377-
freq : string or DateOffset object, optional (default None)
378-
.. deprecated:: 0.18.0
379-
Frequency to conform the data to before computing the statistic.
380-
Specified as a frequency string or DateOffset object.
381361
center : boolean, default False
382362
Set the labels at the center of the window.
383363
win_type : string, default None
384-
Provide a window type. See the notes below.
364+
Provide a window type. If ``None``, all points are evenly weighted.
365+
See the notes below for further information.
385366
on : string, optional
386367
For a DataFrame, column on which to calculate
387368
the rolling window, rather than the index
@@ -479,10 +460,6 @@ class Window(_Window):
479460
By default, the result is set to the right edge of the window. This can be
480461
changed to the center of the window by setting ``center=True``.
481462
482-
The `freq` keyword is used to conform time series data to a specified
483-
frequency by resampling the data. This is done with the default parameters
484-
of :meth:`~pandas.Series.resample` (i.e. using the `mean`).
485-
486463
To learn more about the offsets & frequency strings, please see `this link
487464
<http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases>`__.
488465
@@ -506,6 +483,11 @@ class Window(_Window):
506483
If ``win_type=None`` all points are evenly weighted. To learn more about
507484
different window types see `scipy.signal window functions
508485
<https://docs.scipy.org/doc/scipy/reference/signal.html#window-functions>`__.
486+
487+
See Also
488+
--------
489+
expanding : Provides expanding transformations.
490+
ewm : Provides exponential weighted functions
509491
"""
510492

511493
def validate(self):
@@ -876,8 +858,6 @@ def sum(self, *args, **kwargs):
876858

877859
def max(self, how=None, *args, **kwargs):
878860
nv.validate_window_func('max', args, kwargs)
879-
if self.freq is not None and how is None:
880-
how = 'max'
881861
return self._apply('roll_max', 'max', how=how, **kwargs)
882862

883863
_shared_docs['min'] = dedent("""
@@ -891,8 +871,6 @@ def max(self, how=None, *args, **kwargs):
891871

892872
def min(self, how=None, *args, **kwargs):
893873
nv.validate_window_func('min', args, kwargs)
894-
if self.freq is not None and how is None:
895-
how = 'min'
896874
return self._apply('roll_min', 'min', how=how, **kwargs)
897875

898876
def mean(self, *args, **kwargs):
@@ -909,8 +887,6 @@ def mean(self, *args, **kwargs):
909887
Method for down- or re-sampling""")
910888

911889
def median(self, how=None, **kwargs):
912-
if self.freq is not None and how is None:
913-
how = 'median'
914890
return self._apply('roll_median_c', 'median', how=how, **kwargs)
915891

916892
_shared_docs['std'] = dedent("""
@@ -1060,9 +1036,9 @@ def corr(self, other=None, pairwise=None, **kwargs):
10601036

10611037
def _get_corr(a, b):
10621038
a = a.rolling(window=window, min_periods=self.min_periods,
1063-
freq=self.freq, center=self.center)
1039+
center=self.center)
10641040
b = b.rolling(window=window, min_periods=self.min_periods,
1065-
freq=self.freq, center=self.center)
1041+
center=self.center)
10661042

10671043
return a.cov(b, **kwargs) / (a.std(**kwargs) * b.std(**kwargs))
10681044

@@ -1136,7 +1112,7 @@ def _validate_monotonic(self):
11361112
"monotonic".format(formatted))
11371113

11381114
def _validate_freq(self):
1139-
""" validate & return our freq """
1115+
""" validate & return window frequency """
11401116
from pandas.tseries.frequencies import to_offset
11411117
try:
11421118
return to_offset(self.window)
@@ -1346,10 +1322,6 @@ class Expanding(_Rolling_and_Expanding):
13461322
min_periods : int, default None
13471323
Minimum number of observations in window required to have a value
13481324
(otherwise result is NA).
1349-
freq : string or DateOffset object, optional (default None)
1350-
.. deprecated:: 0.18.0
1351-
Frequency to conform the data to before computing the statistic.
1352-
Specified as a frequency string or DateOffset object.
13531325
center : boolean, default False
13541326
Set the labels at the center of the window.
13551327
axis : int or string, default 0
@@ -1382,17 +1354,18 @@ class Expanding(_Rolling_and_Expanding):
13821354
By default, the result is set to the right edge of the window. This can be
13831355
changed to the center of the window by setting ``center=True``.
13841356
1385-
The `freq` keyword is used to conform time series data to a specified
1386-
frequency by resampling the data. This is done with the default parameters
1387-
of :meth:`~pandas.Series.resample` (i.e. using the `mean`).
1357+
See Also
1358+
--------
1359+
rolling : Provides rolling window calculations
1360+
ewm : Provides exponential weighted functions
13881361
"""
13891362

1390-
_attributes = ['min_periods', 'freq', 'center', 'axis']
1363+
_attributes = ['min_periods', 'center', 'axis']
13911364

1392-
def __init__(self, obj, min_periods=1, freq=None, center=False, axis=0,
1365+
def __init__(self, obj, min_periods=1, center=False, axis=0,
13931366
**kwargs):
13941367
super(Expanding, self).__init__(obj=obj, min_periods=min_periods,
1395-
freq=freq, center=center, axis=axis)
1368+
center=center, axis=axis)
13961369

13971370
@property
13981371
def _constructor(self):
@@ -1611,9 +1584,6 @@ class EWM(_Rolling):
16111584
min_periods : int, default 0
16121585
Minimum number of observations in window required to have a value
16131586
(otherwise result is NA).
1614-
freq : None or string alias / date offset object, default=None
1615-
.. deprecated:: 0.18.0
1616-
Frequency to conform to before computing statistic
16171587
adjust : boolean, default True
16181588
Divide by decaying adjustment factor in beginning periods to account
16191589
for imbalance in relative weightings (viewing EWMA as a moving average)
@@ -1651,10 +1621,6 @@ class EWM(_Rolling):
16511621
parameter descriptions above; see the link at the end of this section for
16521622
a detailed explanation.
16531623
1654-
The `freq` keyword is used to conform time series data to a specified
1655-
frequency by resampling the data. This is done with the default parameters
1656-
of :meth:`~pandas.Series.resample` (i.e. using the `mean`).
1657-
16581624
When adjust is True (default), weighted averages are calculated using
16591625
weights (1-alpha)**(n-1), (1-alpha)**(n-2), ..., 1-alpha, 1.
16601626
@@ -1674,16 +1640,20 @@ class EWM(_Rolling):
16741640
16751641
More details can be found at
16761642
http://pandas.pydata.org/pandas-docs/stable/computation.html#exponentially-weighted-windows
1643+
1644+
See Also
1645+
--------
1646+
rolling : Provides rolling window calculations
1647+
expanding : Provides expanding transformations.
16771648
"""
1678-
_attributes = ['com', 'min_periods', 'freq', 'adjust', 'ignore_na', 'axis']
1649+
_attributes = ['com', 'min_periods', 'adjust', 'ignore_na', 'axis']
16791650

16801651
def __init__(self, obj, com=None, span=None, halflife=None, alpha=None,
1681-
min_periods=0, freq=None, adjust=True, ignore_na=False,
1652+
min_periods=0, adjust=True, ignore_na=False,
16821653
axis=0):
16831654
self.obj = obj
16841655
self.com = _get_center_of_mass(com, span, halflife, alpha)
16851656
self.min_periods = min_periods
1686-
self.freq = freq
16871657
self.adjust = adjust
16881658
self.ignore_na = ignore_na
16891659
self.axis = axis

‎pandas/stats/moments.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ def ensure_compat(dispatch, name, arg, func_kw=None, *args, **kwargs):
208208
if value is not None:
209209
kwds[k] = value
210210

211+
# TODO: the below is only in place temporary until this module is removed.
212+
kwargs.pop('freq', None) # freq removed in 0.22
211213
# how is a keyword that if not-None should be in kwds
212214
how = kwargs.pop('how', None)
213215
if how is not None:
@@ -680,7 +682,6 @@ def f(arg, min_periods=1, freq=None, **kwargs):
680682
name,
681683
arg,
682684
min_periods=min_periods,
683-
freq=freq,
684685
func_kw=func_kw,
685686
**kwargs)
686687
return f

‎pandas/tests/test_window.py

Lines changed: 27 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -284,33 +284,6 @@ def test_preserve_metadata(self):
284284
assert s2.name == 'foo'
285285
assert s3.name == 'foo'
286286

287-
def test_how_compat(self):
288-
# in prior versions, we would allow how to be used in the resample
289-
# now that its deprecated, we need to handle this in the actual
290-
# aggregation functions
291-
s = Series(np.random.randn(20),
292-
index=pd.date_range('1/1/2000', periods=20, freq='12H'))
293-
294-
for how in ['min', 'max', 'median']:
295-
for op in ['mean', 'sum', 'std', 'var', 'kurt', 'skew']:
296-
for t in ['rolling', 'expanding']:
297-
298-
with catch_warnings(record=True):
299-
300-
dfunc = getattr(pd, "{0}_{1}".format(t, op))
301-
if dfunc is None:
302-
continue
303-
304-
if t == 'rolling':
305-
kwargs = {'window': 5}
306-
else:
307-
kwargs = {}
308-
result = dfunc(s, freq='D', how=how, **kwargs)
309-
310-
expected = getattr(
311-
getattr(s, t)(freq='D', **kwargs), op)(how=how)
312-
tm.assert_series_equal(result, expected)
313-
314287

315288
class TestWindow(Base):
316289

@@ -1452,22 +1425,18 @@ def get_result(arr, window, min_periods=None, center=False):
14521425
def _check_structures(self, f, static_comp, name=None,
14531426
has_min_periods=True, has_time_rule=True,
14541427
has_center=True, fill_value=None, **kwargs):
1455-
def get_result(obj, window, min_periods=None, freq=None, center=False):
1428+
def get_result(obj, window, min_periods=None, center=False):
14561429

14571430
# check via the API calls if name is provided
14581431
if name is not None:
1459-
1460-
# catch a freq deprecation warning if freq is provided and not
1461-
# None
1462-
with catch_warnings(record=True):
1463-
r = obj.rolling(window=window, min_periods=min_periods,
1464-
freq=freq, center=center)
1432+
r = obj.rolling(window=window, min_periods=min_periods,
1433+
center=center)
14651434
return getattr(r, name)(**kwargs)
14661435

14671436
# check via the moments API
14681437
with catch_warnings(record=True):
14691438
return f(obj, window=window, min_periods=min_periods,
1470-
freq=freq, center=center, **kwargs)
1439+
center=center, **kwargs)
14711440

14721441
series_result = get_result(self.series, window=50)
14731442
frame_result = get_result(self.frame, window=50)
@@ -1479,17 +1448,17 @@ def get_result(obj, window, min_periods=None, freq=None, center=False):
14791448
if has_time_rule:
14801449
win = 25
14811450
minp = 10
1451+
series = self.series[::2].resample('B').mean()
1452+
frame = self.frame[::2].resample('B').mean()
14821453

14831454
if has_min_periods:
1484-
series_result = get_result(self.series[::2], window=win,
1485-
min_periods=minp, freq='B')
1486-
frame_result = get_result(self.frame[::2], window=win,
1487-
min_periods=minp, freq='B')
1455+
series_result = get_result(series, window=win,
1456+
min_periods=minp)
1457+
frame_result = get_result(frame, window=win,
1458+
min_periods=minp)
14881459
else:
1489-
series_result = get_result(self.series[::2], window=win,
1490-
freq='B')
1491-
frame_result = get_result(self.frame[::2], window=win,
1492-
freq='B')
1460+
series_result = get_result(series, window=win)
1461+
frame_result = get_result(frame, window=win)
14931462

14941463
last_date = series_result.index[-1]
14951464
prev_date = last_date - 24 * offsets.BDay()
@@ -2035,15 +2004,11 @@ class TestMomentsConsistency(Base):
20352004
(np.nanmax, 1, 'max'),
20362005
(np.nanmin, 1, 'min'),
20372006
(np.nansum, 1, 'sum'),
2007+
(np.nanmean, 1, 'mean'),
2008+
(lambda v: np.nanstd(v, ddof=1), 1, 'std'),
2009+
(lambda v: np.nanvar(v, ddof=1), 1, 'var'),
2010+
(np.nanmedian, 1, 'median'),
20382011
]
2039-
if np.__version__ >= LooseVersion('1.8.0'):
2040-
base_functions += [
2041-
(np.nanmean, 1, 'mean'),
2042-
(lambda v: np.nanstd(v, ddof=1), 1, 'std'),
2043-
(lambda v: np.nanvar(v, ddof=1), 1, 'var'),
2044-
]
2045-
if np.__version__ >= LooseVersion('1.9.0'):
2046-
base_functions += [(np.nanmedian, 1, 'median'), ]
20472012
no_nan_functions = [
20482013
(np.max, None, 'max'),
20492014
(np.min, None, 'min'),
@@ -2597,9 +2562,9 @@ def test_expanding_apply(self):
25972562
ser = Series([])
25982563
tm.assert_series_equal(ser, ser.expanding().apply(lambda x: x.mean()))
25992564

2600-
def expanding_mean(x, min_periods=1, freq=None):
2565+
def expanding_mean(x, min_periods=1):
26012566
return mom.expanding_apply(x, lambda x: x.mean(),
2602-
min_periods=min_periods, freq=freq)
2567+
min_periods=min_periods)
26032568

26042569
self._check_expanding(expanding_mean, np.mean)
26052570

@@ -3052,8 +3017,7 @@ def test_rolling_max_gh6297(self):
30523017

30533018
expected = Series([1.0, 2.0, 6.0, 4.0, 5.0],
30543019
index=[datetime(1975, 1, i, 0) for i in range(1, 6)])
3055-
with catch_warnings(record=True):
3056-
x = series.rolling(window=1, freq='D').max()
3020+
x = series.resample('D').max().rolling(window=1).max()
30573021
tm.assert_series_equal(expected, x)
30583022

30593023
def test_rolling_max_how_resample(self):
@@ -3071,24 +3035,21 @@ def test_rolling_max_how_resample(self):
30713035
# Default how should be max
30723036
expected = Series([0.0, 1.0, 2.0, 3.0, 20.0],
30733037
index=[datetime(1975, 1, i, 0) for i in range(1, 6)])
3074-
with catch_warnings(record=True):
3075-
x = series.rolling(window=1, freq='D').max()
3038+
x = series.resample('D').max().rolling(window=1).max()
30763039
tm.assert_series_equal(expected, x)
30773040

30783041
# Now specify median (10.0)
30793042
expected = Series([0.0, 1.0, 2.0, 3.0, 10.0],
30803043
index=[datetime(1975, 1, i, 0) for i in range(1, 6)])
3081-
with catch_warnings(record=True):
3082-
x = series.rolling(window=1, freq='D').max(how='median')
3044+
x = series.resample('D').median().rolling(window=1).max(how='median')
30833045
tm.assert_series_equal(expected, x)
30843046

30853047
# Now specify mean (4+10+20)/3
30863048
v = (4.0 + 10.0 + 20.0) / 3.0
30873049
expected = Series([0.0, 1.0, 2.0, 3.0, v],
30883050
index=[datetime(1975, 1, i, 0) for i in range(1, 6)])
3089-
with catch_warnings(record=True):
3090-
x = series.rolling(window=1, freq='D').max(how='mean')
3091-
tm.assert_series_equal(expected, x)
3051+
x = series.resample('D').mean().rolling(window=1).max(how='mean')
3052+
tm.assert_series_equal(expected, x)
30923053

30933054
def test_rolling_min_how_resample(self):
30943055

@@ -3105,9 +3066,8 @@ def test_rolling_min_how_resample(self):
31053066
# Default how should be min
31063067
expected = Series([0.0, 1.0, 2.0, 3.0, 4.0],
31073068
index=[datetime(1975, 1, i, 0) for i in range(1, 6)])
3108-
with catch_warnings(record=True):
3109-
r = series.rolling(window=1, freq='D')
3110-
tm.assert_series_equal(expected, r.min())
3069+
r = series.resample('D').min().rolling(window=1)
3070+
tm.assert_series_equal(expected, r.min())
31113071

31123072
def test_rolling_median_how_resample(self):
31133073

@@ -3124,9 +3084,8 @@ def test_rolling_median_how_resample(self):
31243084
# Default how should be median
31253085
expected = Series([0.0, 1.0, 2.0, 3.0, 10],
31263086
index=[datetime(1975, 1, i, 0) for i in range(1, 6)])
3127-
with catch_warnings(record=True):
3128-
x = series.rolling(window=1, freq='D').median()
3129-
tm.assert_series_equal(expected, x)
3087+
x = series.resample('D').median().rolling(window=1).median()
3088+
tm.assert_series_equal(expected, x)
31303089

31313090
def test_rolling_median_memory_error(self):
31323091
# GH11722

0 commit comments

Comments
 (0)
Please sign in to comment.