-
-
Notifications
You must be signed in to change notification settings - Fork 18.6k
ENH: Rolling window with step size (GH-15354) #45765
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
Changes from all commits
ccc94a9
21eea5b
ebb27f5
a1d6954
687e8a4
527e0e0
9c225c0
3a9c089
675810f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,9 @@ | |
center passed from the top level rolling API | ||
closed : str, default None | ||
closed passed from the top level rolling API | ||
step : int, default None | ||
step passed from the top level rolling API | ||
.. versionadded:: 1.5 | ||
win_type : str, default None | ||
win_type passed from the top level rolling API | ||
|
||
|
@@ -62,6 +65,7 @@ def get_window_bounds( | |
min_periods: int | None = None, | ||
center: bool | None = None, | ||
closed: str | None = None, | ||
step: int | None = None, | ||
) -> tuple[np.ndarray, np.ndarray]: | ||
|
||
raise NotImplementedError | ||
|
@@ -77,14 +81,15 @@ def get_window_bounds( | |
min_periods: int | None = None, | ||
center: bool | None = None, | ||
closed: str | None = None, | ||
step: int | None = None, | ||
) -> tuple[np.ndarray, np.ndarray]: | ||
|
||
if center: | ||
offset = (self.window_size - 1) // 2 | ||
else: | ||
offset = 0 | ||
|
||
end = np.arange(1 + offset, num_values + 1 + offset, dtype="int64") | ||
end = np.arange(1 + offset, num_values + 1 + offset, step, dtype="int64") | ||
start = end - self.window_size | ||
if closed in ["left", "both"]: | ||
start -= 1 | ||
|
@@ -107,8 +112,12 @@ def get_window_bounds( | |
min_periods: int | None = None, | ||
center: bool | None = None, | ||
closed: str | None = None, | ||
step: int | None = None, | ||
) -> tuple[np.ndarray, np.ndarray]: | ||
|
||
if step is not None: | ||
raise NotImplementedError("step not implemented for variable window") | ||
|
||
# error: Argument 4 to "calculate_variable_window_bounds" has incompatible | ||
# type "Optional[bool]"; expected "bool" | ||
# error: Argument 6 to "calculate_variable_window_bounds" has incompatible | ||
|
@@ -119,6 +128,7 @@ def get_window_bounds( | |
min_periods, | ||
center, # type: ignore[arg-type] | ||
closed, | ||
1, | ||
self.index_array, # type: ignore[arg-type] | ||
) | ||
|
||
|
@@ -145,8 +155,14 @@ def get_window_bounds( | |
min_periods: int | None = None, | ||
center: bool | None = None, | ||
closed: str | None = None, | ||
step: int | None = None, | ||
rtpsw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) -> tuple[np.ndarray, np.ndarray]: | ||
|
||
if step is not None: | ||
raise NotImplementedError("step not implemented for variable offset window") | ||
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. tests hit this? 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. Yes, and there are multiple instances of this error in this file that get tested. This is done using 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. Can't these check be performed in 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. yeah i agree should move this check to be more consistent |
||
if num_values <= 0: | ||
return np.empty(0, dtype="int64"), np.empty(0, dtype="int64") | ||
|
||
# if windows is variable, default is 'right', otherwise default is 'both' | ||
if closed is None: | ||
closed = "right" if self.index is not None else "both" | ||
|
@@ -215,12 +231,15 @@ def get_window_bounds( | |
min_periods: int | None = None, | ||
center: bool | None = None, | ||
closed: str | None = None, | ||
step: int | None = None, | ||
) -> tuple[np.ndarray, np.ndarray]: | ||
|
||
return ( | ||
np.zeros(num_values, dtype=np.int64), | ||
np.arange(1, num_values + 1, dtype=np.int64), | ||
) | ||
if step is not None: | ||
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. same here |
||
raise NotImplementedError("step not implemented for expanding window") | ||
|
||
end = np.arange(1, num_values + 1, dtype=np.int64) | ||
start = np.zeros(len(end), dtype=np.int64) | ||
return start, end | ||
|
||
|
||
class FixedForwardWindowIndexer(BaseIndexer): | ||
|
@@ -256,6 +275,7 @@ def get_window_bounds( | |
min_periods: int | None = None, | ||
center: bool | None = None, | ||
closed: str | None = None, | ||
step: int | None = None, | ||
) -> tuple[np.ndarray, np.ndarray]: | ||
|
||
if center: | ||
|
@@ -264,11 +284,13 @@ def get_window_bounds( | |
raise ValueError( | ||
"Forward-looking windows don't support setting the closed argument" | ||
) | ||
if step is None: | ||
step = 1 | ||
|
||
start = np.arange(num_values, dtype="int64") | ||
start = np.arange(0, num_values, step, dtype="int64") | ||
end = start + self.window_size | ||
if self.window_size: | ||
end[-self.window_size :] = num_values | ||
end = np.clip(end, 0, num_values) | ||
|
||
return start, end | ||
|
||
|
@@ -319,7 +341,11 @@ def get_window_bounds( | |
min_periods: int | None = None, | ||
center: bool | None = None, | ||
closed: str | None = None, | ||
step: int | None = None, | ||
) -> tuple[np.ndarray, np.ndarray]: | ||
if step is not None: | ||
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. same |
||
raise NotImplementedError("step not implemented for groupby window") | ||
|
||
# 1) For each group, get the indices that belong to the group | ||
# 2) Use the indices to calculate the start & end bounds of the window | ||
# 3) Append the window bounds in group order | ||
|
@@ -339,7 +365,7 @@ def get_window_bounds( | |
**self.indexer_kwargs, | ||
) | ||
start, end = indexer.get_window_bounds( | ||
len(indices), min_periods, center, closed | ||
len(indices), min_periods, center, closed, step | ||
) | ||
start = start.astype(np.int64) | ||
end = end.astype(np.int64) | ||
|
@@ -358,6 +384,8 @@ def get_window_bounds( | |
) | ||
start_arrays.append(window_indices.take(ensure_platform_int(start))) | ||
end_arrays.append(window_indices.take(ensure_platform_int(end))) | ||
if len(start_arrays) == 0: | ||
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. blank line here |
||
return np.array([], dtype=np.int64), np.array([], dtype=np.int64) | ||
start = np.concatenate(start_arrays) | ||
end = np.concatenate(end_arrays) | ||
return start, end | ||
|
@@ -373,6 +401,14 @@ def get_window_bounds( | |
min_periods: int | None = None, | ||
center: bool | None = None, | ||
closed: str | None = None, | ||
step: int | None = None, | ||
) -> tuple[np.ndarray, np.ndarray]: | ||
|
||
return np.array([0], dtype=np.int64), np.array([num_values], dtype=np.int64) | ||
if step is not None: | ||
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. same |
||
raise NotImplementedError( | ||
"step not implemented for exponentail moving window" | ||
) | ||
return ( | ||
np.array([0], dtype=np.int64), | ||
np.array([num_values], dtype=np.int64), | ||
) |
Uh oh!
There was an error while loading. Please reload this page.