@@ -229,6 +229,11 @@ def _validate(self) -> None:
229229 )
230230 if self .method not in ["table" , "single" ]:
231231 raise ValueError ("method must be 'table' or 'single" )
232+ if self .step is not None :
233+ if not is_integer (self .step ):
234+ raise ValueError ("step must be an integer" )
235+ elif self .step < 0 :
236+ raise ValueError ("step must be >= 0" )
232237
233238 def _check_window_bounds (
234239 self , start : np .ndarray , end : np .ndarray , num_vals : int
@@ -238,16 +243,14 @@ def _check_window_bounds(
238243 f"start ({ len (start )} ) and end ({ len (end )} ) bounds must be the "
239244 f"same length"
240245 )
241- elif not isinstance (self ._get_window_indexer (), GroupbyIndexer ) and len (
242- start
243- ) != (num_vals + (self .step or 1 ) - 1 ) // (self .step or 1 ):
246+ elif len (start ) != (num_vals + (self .step or 1 ) - 1 ) // (self .step or 1 ):
244247 raise ValueError (
245248 f"start and end bounds ({ len (start )} ) must be the same length "
246249 f"as the object ({ num_vals } ) divided by the step ({ self .step } ) "
247250 f"if given and rounded up"
248251 )
249252
250- def _slice_index (self , index : Index , result : Sized | None = None ) -> Index :
253+ def _slice_axis_for_step (self , index : Index , result : Sized | None = None ) -> Index :
251254 """
252255 Slices the index for a given result and the preset step.
253256 """
@@ -446,7 +449,7 @@ def _apply_series(
446449 raise DataError ("No numeric types to aggregate" ) from err
447450
448451 result = homogeneous_func (values )
449- index = self ._slice_index (obj .index , result )
452+ index = self ._slice_axis_for_step (obj .index , result )
450453 return obj ._constructor (result , index = index , name = obj .name )
451454
452455 def _apply_blockwise (
@@ -484,7 +487,7 @@ def hfunc(values: ArrayLike) -> ArrayLike:
484487 res_values .append (res )
485488 taker .append (i )
486489
487- index = self ._slice_index (
490+ index = self ._slice_axis_for_step (
488491 obj .index , res_values [0 ] if len (res_values ) > 0 else None
489492 )
490493 df = type (obj )._from_arrays (
@@ -524,7 +527,7 @@ def _apply_tablewise(
524527 values = values .T if self .axis == 1 else values
525528 result = homogeneous_func (values )
526529 result = result .T if self .axis == 1 else result
527- index = self ._slice_index (obj .index , result )
530+ index = self ._slice_axis_for_step (obj .index , result )
528531 columns = (
529532 obj .columns
530533 if result .shape [1 ] == len (obj .columns )
@@ -644,13 +647,13 @@ def _numba_apply(
644647 )
645648 result = aggregator (values , start , end , min_periods , * func_args )
646649 result = result .T if self .axis == 1 else result
647- index = self ._slice_index (obj .index , result )
650+ index = self ._slice_axis_for_step (obj .index , result )
648651 if obj .ndim == 1 :
649652 result = result .squeeze ()
650653 out = obj ._constructor (result , index = index , name = obj .name )
651654 return out
652655 else :
653- columns = self ._slice_index (obj .columns , result .T )
656+ columns = self ._slice_axis_for_step (obj .columns , result .T )
654657 out = obj ._constructor (result , index = index , columns = columns )
655658 return self ._resolve_output (out , obj )
656659
@@ -692,7 +695,7 @@ def __init__(
692695 obj = obj .drop (columns = self ._grouper .names , errors = "ignore" )
693696 # GH 15354
694697 if kwargs .get ("step" ) is not None :
695- raise NotImplementedError ("step not implemented for rolling groupby" )
698+ raise NotImplementedError ("step not implemented for groupby" )
696699 super ().__init__ (obj , * args , ** kwargs )
697700
698701 def _apply (
@@ -938,14 +941,12 @@ class Window(BaseWindow):
938941 The closed parameter with fixed windows is now supported.
939942
940943 step : int, default None
941- When supported, applies ``[::step]`` to the resulting sequence of windows, in a
942- computationally efficient manner. Currently supported only with fixed-length
943- window indexers. Note that using a step argument other than None or 1 will
944- produce a result with a different shape than the input.
945944
946- ..versionadded:: 1.5
945+ ..versionadded:: 1.5.0
947946
948- The step parameter is only supported with fixed windows.
947+ Evaluate the window at every ``step`` result, equivalent to slicing as
948+ ``[::step]``. ``window`` must be an integer. Using a step argument other
949+ than None or 1 will produce a result with a different shape than the input.
949950
950951 method : str {'single', 'table'}, default 'single'
951952
@@ -1605,9 +1606,7 @@ def cov(
16051606 ** kwargs ,
16061607 ):
16071608 if self .step is not None :
1608- raise NotImplementedError (
1609- "step not implemented for rolling and expanding cov"
1610- )
1609+ raise NotImplementedError ("step not implemented for cov" )
16111610
16121611 from pandas import Series
16131612
@@ -1650,11 +1649,8 @@ def corr(
16501649 ddof : int = 1 ,
16511650 ** kwargs ,
16521651 ):
1653-
16541652 if self .step is not None :
1655- raise NotImplementedError (
1656- "step not implemented for rolling and expanding corr"
1657- )
1653+ raise NotImplementedError ("step not implemented for corr" )
16581654
16591655 from pandas import Series
16601656
@@ -1749,24 +1745,16 @@ def _validate(self):
17491745 if self .min_periods is None :
17501746 self .min_periods = 1
17511747
1748+ if self .step is not None :
1749+ raise NotImplementedError (
1750+ "step is not supported with frequency windows"
1751+ )
1752+
17521753 elif isinstance (self .window , BaseIndexer ):
17531754 # Passed BaseIndexer subclass should handle all other rolling kwargs
17541755 pass
17551756 elif not is_integer (self .window ) or self .window < 0 :
17561757 raise ValueError ("window must be an integer 0 or greater" )
1757- # GH 15354:
1758- # validate window indexer parameters do not raise in get_window_bounds
1759- # this cannot be done in BaseWindow._validate because there _get_window_indexer
1760- # would erroneously create a fixed window given a window argument like "1s" due
1761- # to _win_freq_i8 not being set
1762- indexer = self ._get_window_indexer ()
1763- indexer .get_window_bounds (
1764- num_values = 0 ,
1765- min_periods = self .min_periods ,
1766- center = self .center ,
1767- closed = self .closed ,
1768- step = self .step ,
1769- )
17701758
17711759 def _validate_datetimelike_monotonic (self ):
17721760 """
0 commit comments