Skip to content

Commit 7538b79

Browse files
mroeschkeMatt Roeschke
authored andcommitted
REF: Simplifying creation of window indexers internally (pandas-dev#37177)
Co-authored-by: Matt Roeschke <[email protected]>
1 parent a59ebdd commit 7538b79

File tree

2 files changed

+31
-39
lines changed

2 files changed

+31
-39
lines changed

pandas/core/window/expanding.py

+10-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from pandas.util._decorators import Appender, Substitution, doc
99

1010
from pandas.core.window.common import _doc_template, _shared_docs
11-
from pandas.core.window.indexers import ExpandingIndexer, GroupbyIndexer
11+
from pandas.core.window.indexers import BaseIndexer, ExpandingIndexer, GroupbyIndexer
1212
from pandas.core.window.rolling import BaseWindowGroupby, RollingAndExpandingMixin
1313

1414

@@ -68,11 +68,17 @@ def __init__(self, obj, min_periods=1, center=None, axis=0, **kwargs):
6868
def _constructor(self):
6969
return Expanding
7070

71-
def _get_window(
71+
def _get_window_indexer(self) -> BaseIndexer:
72+
"""
73+
Return an indexer class that will compute the window start and end bounds
74+
"""
75+
return ExpandingIndexer()
76+
77+
def _get_cov_corr_window(
7278
self, other: Optional[Union[np.ndarray, FrameOrSeries]] = None, **kwargs
7379
) -> int:
7480
"""
75-
Get the window length over which to perform some operation.
81+
Get the window length over which to perform cov and corr operations.
7682
7783
Parameters
7884
----------
@@ -275,15 +281,10 @@ class ExpandingGroupby(BaseWindowGroupby, Expanding):
275281
Provide a expanding groupby implementation.
276282
"""
277283

278-
def _get_window_indexer(self, window: int) -> GroupbyIndexer:
284+
def _get_window_indexer(self) -> GroupbyIndexer:
279285
"""
280286
Return an indexer class that will compute the window start and end bounds
281287
282-
Parameters
283-
----------
284-
window : int
285-
window size for FixedWindowIndexer (unused)
286-
287288
Returns
288289
-------
289290
GroupbyIndexer

pandas/core/window/rolling.py

+21-30
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,9 @@ def __getattr__(self, attr: str):
213213
def _dir_additions(self):
214214
return self.obj._dir_additions()
215215

216-
def _get_window(
216+
def _get_cov_corr_window(
217217
self, other: Optional[Union[np.ndarray, FrameOrSeries]] = None
218-
) -> int:
218+
) -> Optional[Union[int, timedelta, BaseOffset, BaseIndexer]]:
219219
"""
220220
Return window length.
221221
@@ -228,8 +228,6 @@ def _get_window(
228228
-------
229229
window : int
230230
"""
231-
if isinstance(self.window, BaseIndexer):
232-
return self.min_periods or 0
233231
return self.window
234232

235233
@property
@@ -249,11 +247,10 @@ def __repr__(self) -> str:
249247
return f"{self._window_type} [{attrs}]"
250248

251249
def __iter__(self):
252-
window = self._get_window()
253250
obj = self._create_data(self._selected_obj)
254-
index = self._get_window_indexer(window=window)
251+
indexer = self._get_window_indexer()
255252

256-
start, end = index.get_window_bounds(
253+
start, end = indexer.get_window_bounds(
257254
num_values=len(obj),
258255
min_periods=self.min_periods,
259256
center=self.center,
@@ -340,15 +337,17 @@ def _get_roll_func(self, func_name: str) -> Callable[..., Any]:
340337
)
341338
return window_func
342339

343-
def _get_window_indexer(self, window: int) -> BaseIndexer:
340+
def _get_window_indexer(self) -> BaseIndexer:
344341
"""
345342
Return an indexer class that will compute the window start and end bounds
346343
"""
347344
if isinstance(self.window, BaseIndexer):
348345
return self.window
349346
if self.is_freq_type:
350-
return VariableWindowIndexer(index_array=self._on.asi8, window_size=window)
351-
return FixedWindowIndexer(window_size=window)
347+
return VariableWindowIndexer(
348+
index_array=self._on.asi8, window_size=self.window
349+
)
350+
return FixedWindowIndexer(window_size=self.window)
352351

353352
def _apply_series(
354353
self, homogeneous_func: Callable[..., ArrayLike], name: Optional[str] = None
@@ -428,8 +427,7 @@ def _apply(
428427
-------
429428
y : type of input
430429
"""
431-
window = self._get_window()
432-
window_indexer = self._get_window_indexer(window)
430+
window_indexer = self._get_window_indexer()
433431
min_periods = (
434432
self.min_periods
435433
if self.min_periods is not None
@@ -1750,14 +1748,10 @@ def cov(self, other=None, pairwise=None, ddof=1, **kwargs):
17501748
# GH 32865. We leverage rolling.mean, so we pass
17511749
# to the rolling constructors the data used when constructing self:
17521750
# window width, frequency data, or a BaseIndexer subclass
1753-
if isinstance(self.window, BaseIndexer):
1754-
window = self.window
1755-
else:
1756-
# GH 16058: offset window
1757-
if self.is_freq_type:
1758-
window = self.win_freq
1759-
else:
1760-
window = self._get_window(other)
1751+
# GH 16058: offset window
1752+
window = (
1753+
self._get_cov_corr_window(other) if not self.is_freq_type else self.win_freq
1754+
)
17611755

17621756
def _get_cov(X, Y):
17631757
# GH #12373 : rolling functions error on float32 data
@@ -1899,10 +1893,10 @@ def corr(self, other=None, pairwise=None, **kwargs):
18991893
# GH 32865. We leverage rolling.cov and rolling.std here, so we pass
19001894
# to the rolling constructors the data used when constructing self:
19011895
# window width, frequency data, or a BaseIndexer subclass
1902-
if isinstance(self.window, BaseIndexer):
1903-
window = self.window
1904-
else:
1905-
window = self._get_window(other) if not self.is_freq_type else self.win_freq
1896+
# GH 16058: offset window
1897+
window = (
1898+
self._get_cov_corr_window(other) if not self.is_freq_type else self.win_freq
1899+
)
19061900

19071901
def _get_corr(a, b):
19081902
a = a.rolling(
@@ -2208,28 +2202,25 @@ class RollingGroupby(BaseWindowGroupby, Rolling):
22082202
Provide a rolling groupby implementation.
22092203
"""
22102204

2211-
def _get_window_indexer(self, window: int) -> GroupbyIndexer:
2205+
def _get_window_indexer(self) -> GroupbyIndexer:
22122206
"""
22132207
Return an indexer class that will compute the window start and end bounds
22142208
2215-
Parameters
2216-
----------
2217-
window : int
2218-
window size for FixedWindowIndexer
2219-
22202209
Returns
22212210
-------
22222211
GroupbyIndexer
22232212
"""
22242213
rolling_indexer: Type[BaseIndexer]
22252214
indexer_kwargs: Optional[Dict[str, Any]] = None
22262215
index_array = self._on.asi8
2216+
window = self.window
22272217
if isinstance(self.window, BaseIndexer):
22282218
rolling_indexer = type(self.window)
22292219
indexer_kwargs = self.window.__dict__
22302220
assert isinstance(indexer_kwargs, dict) # for mypy
22312221
# We'll be using the index of each group later
22322222
indexer_kwargs.pop("index_array", None)
2223+
window = 0
22332224
elif self.is_freq_type:
22342225
rolling_indexer = VariableWindowIndexer
22352226
else:

0 commit comments

Comments
 (0)