-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
CLN: Simplify rolling.py helper functions #30672
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
cf69289
Remove get_index
2ea57cb
Remove unecessary timedelta coersion
473c1e9
clean up weight function getter
1274a3a
Refactor _offset
a0342a2
Remove _require_min_periods
99b2a06
Merge remote-tracking branch 'upstream/master' into clean_rolling
0f59877
deprivatize and move to common functions
4734394
Merge remote-tracking branch 'upstream/master' into clean_rolling
74ed387
Deprivatize helper functions
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,6 @@ | |
is_integer_dtype, | ||
is_list_like, | ||
is_scalar, | ||
is_timedelta64_dtype, | ||
needs_i8_conversion, | ||
) | ||
from pandas.core.dtypes.generic import ( | ||
|
@@ -43,11 +42,11 @@ | |
WindowGroupByMixin, | ||
_doc_template, | ||
_flex_binary_moment, | ||
_offset, | ||
_shared_docs, | ||
_use_window, | ||
_zsqrt, | ||
calculate_center_offset, | ||
calculate_min_periods, | ||
get_weighted_roll_func, | ||
zsqrt, | ||
) | ||
from pandas.core.window.indexers import ( | ||
BaseIndexer, | ||
|
@@ -252,19 +251,6 @@ def __iter__(self): | |
url = "https://github.com/pandas-dev/pandas/issues/11704" | ||
raise NotImplementedError(f"See issue #11704 {url}") | ||
|
||
def _get_index(self) -> Optional[np.ndarray]: | ||
""" | ||
Return integer representations as an ndarray if index is frequency. | ||
|
||
Returns | ||
------- | ||
None or ndarray | ||
""" | ||
|
||
if self.is_freq_type: | ||
return self._on.asi8 | ||
return None | ||
|
||
def _prep_values(self, values: Optional[np.ndarray] = None) -> np.ndarray: | ||
"""Convert input to numpy arrays for Cython routines""" | ||
if values is None: | ||
|
@@ -305,17 +291,6 @@ def _wrap_result(self, result, block=None, obj=None): | |
|
||
if isinstance(result, np.ndarray): | ||
|
||
# coerce if necessary | ||
if block is not None: | ||
if is_timedelta64_dtype(block.values.dtype): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this not reachable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't think so. Our test suite includes timedelta64 which doesn't his this branch. |
||
# TODO: do we know what result.dtype is at this point? | ||
# i.e. can we just do an astype? | ||
from pandas import to_timedelta | ||
|
||
result = to_timedelta(result.ravel(), unit="ns").values.reshape( | ||
result.shape | ||
) | ||
|
||
if result.ndim == 1: | ||
from pandas import Series | ||
|
||
|
@@ -384,14 +359,11 @@ def _center_window(self, result, window) -> np.ndarray: | |
if self.axis > result.ndim - 1: | ||
raise ValueError("Requested axis is larger then no. of argument dimensions") | ||
|
||
offset = _offset(window, True) | ||
offset = calculate_center_offset(window) | ||
if offset > 0: | ||
if isinstance(result, (ABCSeries, ABCDataFrame)): | ||
result = result.slice_shift(-offset, axis=self.axis) | ||
else: | ||
lead_indexer = [slice(None)] * result.ndim | ||
lead_indexer[self.axis] = slice(offset, None) | ||
result = np.copy(result[tuple(lead_indexer)]) | ||
lead_indexer = [slice(None)] * result.ndim | ||
lead_indexer[self.axis] = slice(offset, None) | ||
result = np.copy(result[tuple(lead_indexer)]) | ||
return result | ||
|
||
def _get_roll_func(self, func_name: str) -> Callable: | ||
|
@@ -424,17 +396,15 @@ def _get_cython_func_type(self, func: str) -> Callable: | |
return self._get_roll_func(f"{func}_variable") | ||
return partial(self._get_roll_func(f"{func}_fixed"), win=self._get_window()) | ||
|
||
def _get_window_indexer( | ||
self, index_as_array: Optional[np.ndarray], window: int | ||
) -> BaseIndexer: | ||
def _get_window_indexer(self, window: int) -> BaseIndexer: | ||
""" | ||
Return an indexer class that will compute the window start and end bounds | ||
""" | ||
if isinstance(self.window, BaseIndexer): | ||
return self.window | ||
if self.is_freq_type: | ||
return VariableWindowIndexer(index_array=index_as_array, window_size=window) | ||
return FixedWindowIndexer(index_array=index_as_array, window_size=window) | ||
return VariableWindowIndexer(index_array=self._on.asi8, window_size=window) | ||
return FixedWindowIndexer(window_size=window) | ||
|
||
def _apply( | ||
self, | ||
|
@@ -476,8 +446,7 @@ def _apply( | |
|
||
blocks, obj = self._create_blocks() | ||
block_list = list(blocks) | ||
index_as_array = self._get_index() | ||
window_indexer = self._get_window_indexer(index_as_array, window) | ||
window_indexer = self._get_window_indexer(window) | ||
|
||
results = [] | ||
exclude: List[Scalar] = [] | ||
|
@@ -498,7 +467,7 @@ def _apply( | |
continue | ||
|
||
# calculation function | ||
offset = _offset(window, center) if center else 0 | ||
offset = calculate_center_offset(window) if center else 0 | ||
additional_nans = np.array([np.nan] * offset) | ||
|
||
if not is_weighted: | ||
|
@@ -1051,15 +1020,6 @@ def _get_window( | |
# GH #15662. `False` makes symmetric window, rather than periodic. | ||
return sig.get_window(win_type, window, False).astype(float) | ||
|
||
def _get_weighted_roll_func( | ||
self, cfunc: Callable, check_minp: Callable, **kwargs | ||
) -> Callable: | ||
def func(arg, window, min_periods=None, closed=None): | ||
minp = check_minp(min_periods, len(window)) | ||
return cfunc(arg, window, minp, **kwargs) | ||
|
||
return func | ||
|
||
_agg_see_also_doc = dedent( | ||
""" | ||
See Also | ||
|
@@ -1127,7 +1087,7 @@ def aggregate(self, func, *args, **kwargs): | |
def sum(self, *args, **kwargs): | ||
nv.validate_window_func("sum", args, kwargs) | ||
window_func = self._get_roll_func("roll_weighted_sum") | ||
window_func = self._get_weighted_roll_func(window_func, _use_window) | ||
window_func = get_weighted_roll_func(window_func) | ||
return self._apply( | ||
window_func, center=self.center, is_weighted=True, name="sum", **kwargs | ||
) | ||
|
@@ -1137,7 +1097,7 @@ def sum(self, *args, **kwargs): | |
def mean(self, *args, **kwargs): | ||
nv.validate_window_func("mean", args, kwargs) | ||
window_func = self._get_roll_func("roll_weighted_mean") | ||
window_func = self._get_weighted_roll_func(window_func, _use_window) | ||
window_func = get_weighted_roll_func(window_func) | ||
return self._apply( | ||
window_func, center=self.center, is_weighted=True, name="mean", **kwargs | ||
) | ||
|
@@ -1147,7 +1107,7 @@ def mean(self, *args, **kwargs): | |
def var(self, ddof=1, *args, **kwargs): | ||
nv.validate_window_func("var", args, kwargs) | ||
window_func = partial(self._get_roll_func("roll_weighted_var"), ddof=ddof) | ||
window_func = self._get_weighted_roll_func(window_func, _use_window) | ||
window_func = get_weighted_roll_func(window_func) | ||
kwargs.pop("name", None) | ||
return self._apply( | ||
window_func, center=self.center, is_weighted=True, name="var", **kwargs | ||
|
@@ -1157,7 +1117,7 @@ def var(self, ddof=1, *args, **kwargs): | |
@Appender(_shared_docs["std"]) | ||
def std(self, ddof=1, *args, **kwargs): | ||
nv.validate_window_func("std", args, kwargs) | ||
return _zsqrt(self.var(ddof=ddof, name="std", **kwargs)) | ||
return zsqrt(self.var(ddof=ddof, name="std", **kwargs)) | ||
|
||
|
||
class _Rolling(_Window): | ||
|
@@ -1211,8 +1171,6 @@ class _Rolling_and_Expanding(_Rolling): | |
def count(self): | ||
|
||
blocks, obj = self._create_blocks() | ||
# Validate the index | ||
self._get_index() | ||
|
||
window = self._get_window() | ||
window = min(window, len(obj)) if not self.center else window | ||
|
@@ -1307,7 +1265,7 @@ def apply( | |
kwargs.pop("_level", None) | ||
kwargs.pop("floor", None) | ||
window = self._get_window() | ||
offset = _offset(window, self.center) | ||
offset = calculate_center_offset(window) if self.center else 0 | ||
if not is_bool(raw): | ||
raise ValueError("raw parameter must be `True` or `False`") | ||
|
||
|
@@ -1478,7 +1436,7 @@ def std(self, ddof=1, *args, **kwargs): | |
window_func = self._get_cython_func_type("roll_var") | ||
|
||
def zsqrt_func(values, begin, end, min_periods): | ||
return _zsqrt(window_func(values, begin, end, min_periods, ddof=ddof)) | ||
return zsqrt(window_func(values, begin, end, min_periods, ddof=ddof)) | ||
|
||
# ddof passed again for compat with groupby.rolling | ||
return self._apply( | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Subtypes for Callable would be helpful here if you know from looking at this what they are