Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 208 additions & 36 deletions pandas/core/indexers/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,13 @@

from pandas._libs.tslibs import BaseOffset
from pandas._libs.window.indexers import calculate_variable_window_bounds
from pandas.util._decorators import Appender

from pandas.core.dtypes.common import ensure_platform_int

from pandas.core.indexes.datetimes import DatetimeIndex

from pandas.tseries.offsets import Nano

get_window_bounds_doc = """
Computes the bounds of a window.
Parameters
----------
num_values : int, default 0
number of values that will be aggregated over
window_size : int, default 0
the number of rows in a window
min_periods : int, default None
min_periods passed from the top level rolling API
center : bool, default None
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
Returns
-------
A tuple of ndarray[int64]s, indicating the boundaries of each
window
"""


class BaseIndexer:
"""
Expand Down Expand Up @@ -95,7 +67,6 @@ def __init__(
for key, value in kwargs.items():
setattr(self, key, value)

@Appender(get_window_bounds_doc)
def get_window_bounds(
self,
num_values: int = 0,
Expand All @@ -104,13 +75,38 @@ def get_window_bounds(
closed: str | None = None,
step: int | None = None,
) -> tuple[np.ndarray, np.ndarray]:
"""
Computes the bounds of a window.
Parameters
----------
num_values : int, default 0
number of values that will be aggregated over
window_size : int, default 0
the number of rows in a window
min_periods : int, default None
min_periods passed from the top level rolling API
center : bool, default None
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
Returns
-------
A tuple of ndarray[int64]s, indicating the boundaries of each
window
"""
raise NotImplementedError


class FixedWindowIndexer(BaseIndexer):
"""Creates window boundaries that are of fixed length."""

@Appender(get_window_bounds_doc)
def get_window_bounds(
self,
num_values: int = 0,
Expand All @@ -119,6 +115,32 @@ def get_window_bounds(
closed: str | None = None,
step: int | None = None,
) -> tuple[np.ndarray, np.ndarray]:
"""
Computes the bounds of a window.
Parameters
----------
num_values : int, default 0
number of values that will be aggregated over
window_size : int, default 0
the number of rows in a window
min_periods : int, default None
min_periods passed from the top level rolling API
center : bool, default None
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
Returns
-------
A tuple of ndarray[int64]s, indicating the boundaries of each
window
"""
if center or self.window_size == 0:
offset = (self.window_size - 1) // 2
else:
Expand All @@ -140,7 +162,6 @@ def get_window_bounds(
class VariableWindowIndexer(BaseIndexer):
"""Creates window boundaries that are of variable length, namely for time series."""

@Appender(get_window_bounds_doc)
def get_window_bounds(
self,
num_values: int = 0,
Expand All @@ -149,6 +170,32 @@ def get_window_bounds(
closed: str | None = None,
step: int | None = None,
) -> tuple[np.ndarray, np.ndarray]:
"""
Computes the bounds of a window.
Parameters
----------
num_values : int, default 0
number of values that will be aggregated over
window_size : int, default 0
the number of rows in a window
min_periods : int, default None
min_periods passed from the top level rolling API
center : bool, default None
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
Returns
-------
A tuple of ndarray[int64]s, indicating the boundaries of each
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
Expand Down Expand Up @@ -240,7 +287,6 @@ def __init__(
raise ValueError("offset must be a DateOffset-like object.")
self.offset = offset

@Appender(get_window_bounds_doc)
def get_window_bounds(
self,
num_values: int = 0,
Expand All @@ -249,6 +295,32 @@ def get_window_bounds(
closed: str | None = None,
step: int | None = None,
) -> tuple[np.ndarray, np.ndarray]:
"""
Computes the bounds of a window.
Parameters
----------
num_values : int, default 0
number of values that will be aggregated over
window_size : int, default 0
the number of rows in a window
min_periods : int, default None
min_periods passed from the top level rolling API
center : bool, default None
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
Returns
-------
A tuple of ndarray[int64]s, indicating the boundaries of each
window
"""
if step is not None:
raise NotImplementedError("step not implemented for variable offset window")
if num_values <= 0:
Expand Down Expand Up @@ -321,7 +393,6 @@ def get_window_bounds(
class ExpandingIndexer(BaseIndexer):
"""Calculate expanding window bounds, mimicking df.expanding()"""

@Appender(get_window_bounds_doc)
def get_window_bounds(
self,
num_values: int = 0,
Expand All @@ -330,6 +401,32 @@ def get_window_bounds(
closed: str | None = None,
step: int | None = None,
) -> tuple[np.ndarray, np.ndarray]:
"""
Computes the bounds of a window.
Parameters
----------
num_values : int, default 0
number of values that will be aggregated over
window_size : int, default 0
the number of rows in a window
min_periods : int, default None
min_periods passed from the top level rolling API
center : bool, default None
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
Returns
-------
A tuple of ndarray[int64]s, indicating the boundaries of each
window
"""
return (
np.zeros(num_values, dtype=np.int64),
np.arange(1, num_values + 1, dtype=np.int64),
Expand Down Expand Up @@ -381,7 +478,6 @@ class FixedForwardWindowIndexer(BaseIndexer):
4 4.0
"""

@Appender(get_window_bounds_doc)
def get_window_bounds(
self,
num_values: int = 0,
Expand All @@ -390,6 +486,32 @@ def get_window_bounds(
closed: str | None = None,
step: int | None = None,
) -> tuple[np.ndarray, np.ndarray]:
"""
Computes the bounds of a window.
Parameters
----------
num_values : int, default 0
number of values that will be aggregated over
window_size : int, default 0
the number of rows in a window
min_periods : int, default None
min_periods passed from the top level rolling API
center : bool, default None
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
Returns
-------
A tuple of ndarray[int64]s, indicating the boundaries of each
window
"""
if center:
raise ValueError("Forward-looking windows can't have center=True")
if closed is not None:
Expand Down Expand Up @@ -446,7 +568,6 @@ def __init__(
**kwargs,
)

@Appender(get_window_bounds_doc)
def get_window_bounds(
self,
num_values: int = 0,
Expand All @@ -455,6 +576,32 @@ def get_window_bounds(
closed: str | None = None,
step: int | None = None,
) -> tuple[np.ndarray, np.ndarray]:
"""
Computes the bounds of a window.
Parameters
----------
num_values : int, default 0
number of values that will be aggregated over
window_size : int, default 0
the number of rows in a window
min_periods : int, default None
min_periods passed from the top level rolling API
center : bool, default None
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
Returns
-------
A tuple of ndarray[int64]s, indicating the boundaries of each
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
Expand Down Expand Up @@ -503,7 +650,6 @@ def get_window_bounds(
class ExponentialMovingWindowIndexer(BaseIndexer):
"""Calculate ewm window bounds (the entire window)"""

@Appender(get_window_bounds_doc)
def get_window_bounds(
self,
num_values: int = 0,
Expand All @@ -512,4 +658,30 @@ def get_window_bounds(
closed: str | None = None,
step: int | None = None,
) -> tuple[np.ndarray, np.ndarray]:
"""
Computes the bounds of a window.
Parameters
----------
num_values : int, default 0
number of values that will be aggregated over
window_size : int, default 0
the number of rows in a window
min_periods : int, default None
min_periods passed from the top level rolling API
center : bool, default None
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
Returns
-------
A tuple of ndarray[int64]s, indicating the boundaries of each
window
"""
return np.array([0], dtype=np.int64), np.array([num_values], dtype=np.int64)
Loading