From 4ec05b0e0256389e18c049d201b3781ae5cd57e3 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Sun, 13 Apr 2025 22:13:02 -0700 Subject: [PATCH 1/5] updated doc and references --- doc/source/reference/groupby.rst | 2 + pandas/core/groupby/groupby.py | 68 ++++++++++++++++++++++++++++++-- test.py | 19 +++++++++ 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 test.py diff --git a/doc/source/reference/groupby.rst b/doc/source/reference/groupby.rst index fc180c8161a7e..ce9aeeb358c19 100644 --- a/doc/source/reference/groupby.rst +++ b/doc/source/reference/groupby.rst @@ -79,6 +79,7 @@ Function application DataFrameGroupBy.cumsum DataFrameGroupBy.describe DataFrameGroupBy.diff + DataFrameGroupBy.ewm DataFrameGroupBy.ffill DataFrameGroupBy.first DataFrameGroupBy.head @@ -130,6 +131,7 @@ Function application SeriesGroupBy.cumsum SeriesGroupBy.describe SeriesGroupBy.diff + SeriesGroupBy.ewm SeriesGroupBy.ffill SeriesGroupBy.first SeriesGroupBy.head diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 9cfeb53821fbc..1780f5c6e7166 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -3824,15 +3824,75 @@ def expanding(self, *args, **kwargs) -> ExpandingGroupby: ) @final - @Substitution(name="groupby") - @Appender(_common_see_also) def ewm(self, *args, **kwargs) -> ExponentialMovingWindowGroupby: """ - Return an ewm grouper, providing ewm functionality per group. + Return an exponentially weighted moving (EWM) grouper, providing EWM functionality per group. + + Parameters + ---------- + *args : tuple + Positional arguments passed to the EWM window constructor. + **kwargs : dict + Keyword arguments passed to the EWM window constructor, such as: + + com : float, optional + Specify decay in terms of center of mass. + ``span``, ``halflife``, and ``alpha`` are alternative ways to specify decay. + span : float, optional + Specify decay in terms of span. + halflife : float, optional + Specify decay in terms of half-life. + alpha : float, optional + Specify smoothing factor directly. + min_periods : int, default 0 + Minimum number of observations in the window required to have a value; + otherwise, result is ``np.nan``. + adjust : bool, default True + Divide by decaying adjustment factor to account for imbalance in relative weights. + ignore_na : bool, default False + Ignore missing values when calculating weights. + times : str or array-like of datetime64, optional + Times corresponding to the observations. + axis : {0 or 'index', 1 or 'columns'}, default 0 + Axis along which the EWM function is applied. Returns ------- - pandas.api.typing.ExponentialMovingWindowGroupby + pandas.core.window.ExponentialMovingWindowGroupby + An object that supports exponentially weighted moving transformations over each group. + + See Also + -------- + Series.ewm : EWM transformations for Series. + DataFrame.ewm : EWM transformations for DataFrames. + Series.groupby : Apply a function groupby to a Series. + DataFrame.groupby : Apply a function groupby. + + Examples + -------- + >>> df = pd.DataFrame( + ... { + ... "Class": ["A", "A", "A", "B", "B", "B"], + ... "Value": [10, 20, 30, 40, 50, 60], + ... } + ... ) + >>> df + Class Value + 0 A 10 + 1 A 20 + 2 A 30 + 3 B 40 + 4 B 50 + 5 B 60 + + >>> df.groupby("Class").ewm(com=0.5).mean().reset_index(drop=True) + Value + 0 10.000000 + 1 17.500000 + 2 26.153846 + 3 40.000000 + 4 47.500000 + 5 56.153846 """ from pandas.core.window import ExponentialMovingWindowGroupby diff --git a/test.py b/test.py new file mode 100644 index 0000000000000..f8d12521d3314 --- /dev/null +++ b/test.py @@ -0,0 +1,19 @@ +import pandas as pd + +pd.set_option('display.float_format', '{:.2f}'.format) + +df = pd.DataFrame([[15.22345676543234567]*6], columns=[1,2,3,4,5,6]) + +# Default float_format works: +print(df) # ✅ Columns display with 2 decimals + +default_fmt = '{:.2f}' +special_fmt = {1: '{:.1f}'} + +formats = { + col: special_fmt.get(col, default_fmt) + for col in df.columns +} + +styled = df.style.format(formats) +styled.to_html("styled.html") From b8cfede16fbe17ff04f2120caaf0ce603f56883c Mon Sep 17 00:00:00 2001 From: arthurlw Date: Sun, 13 Apr 2025 22:20:50 -0700 Subject: [PATCH 2/5] precommit --- pandas/core/groupby/groupby.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 1780f5c6e7166..b5f43784c8fae 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -3836,7 +3836,7 @@ def ewm(self, *args, **kwargs) -> ExponentialMovingWindowGroupby: Keyword arguments passed to the EWM window constructor, such as: com : float, optional - Specify decay in terms of center of mass. + Specify decay in terms of center of mass. ``span``, ``halflife``, and ``alpha`` are alternative ways to specify decay. span : float, optional Specify decay in terms of span. From dc2dd1d013388a8c9ddaa306282b3b3669309edc Mon Sep 17 00:00:00 2001 From: arthurlw Date: Sun, 13 Apr 2025 22:23:36 -0700 Subject: [PATCH 3/5] shortened summary --- pandas/core/groupby/groupby.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index b5f43784c8fae..99963d63ca72e 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -3826,7 +3826,7 @@ def expanding(self, *args, **kwargs) -> ExpandingGroupby: @final def ewm(self, *args, **kwargs) -> ExponentialMovingWindowGroupby: """ - Return an exponentially weighted moving (EWM) grouper, providing EWM functionality per group. + Return an ewm grouper, providing ewm functionality per group. Parameters ---------- From 9fe0dcffda32979226d1e83229478ee7246f1c47 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Mon, 14 Apr 2025 11:18:17 -0700 Subject: [PATCH 4/5] updated according to reviewer suggestions and removed test.py --- pandas/core/groupby/groupby.py | 13 ++++++++----- test.py | 19 ------------------- 2 files changed, 8 insertions(+), 24 deletions(-) delete mode 100644 test.py diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index 99963d63ca72e..bb496c97f479f 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -3837,7 +3837,8 @@ def ewm(self, *args, **kwargs) -> ExponentialMovingWindowGroupby: com : float, optional Specify decay in terms of center of mass. - ``span``, ``halflife``, and ``alpha`` are alternative ways to specify decay. + ``span``, ``halflife``, and ``alpha`` are alternative ways to specify + decay. span : float, optional Specify decay in terms of span. halflife : float, optional @@ -3848,7 +3849,8 @@ def ewm(self, *args, **kwargs) -> ExponentialMovingWindowGroupby: Minimum number of observations in the window required to have a value; otherwise, result is ``np.nan``. adjust : bool, default True - Divide by decaying adjustment factor to account for imbalance in relative weights. + Divide by decaying adjustment factor to account for imbalance in + relative weights. ignore_na : bool, default False Ignore missing values when calculating weights. times : str or array-like of datetime64, optional @@ -3858,8 +3860,9 @@ def ewm(self, *args, **kwargs) -> ExponentialMovingWindowGroupby: Returns ------- - pandas.core.window.ExponentialMovingWindowGroupby - An object that supports exponentially weighted moving transformations over each group. + pandas.api.typing.ExponentialMovingWindowGroupby + An object that supports exponentially weighted moving transformations over + each group. See Also -------- @@ -3885,7 +3888,7 @@ def ewm(self, *args, **kwargs) -> ExponentialMovingWindowGroupby: 4 B 50 5 B 60 - >>> df.groupby("Class").ewm(com=0.5).mean().reset_index(drop=True) + >>> df.groupby("Class").ewm(com=0.5).mean() Value 0 10.000000 1 17.500000 diff --git a/test.py b/test.py deleted file mode 100644 index f8d12521d3314..0000000000000 --- a/test.py +++ /dev/null @@ -1,19 +0,0 @@ -import pandas as pd - -pd.set_option('display.float_format', '{:.2f}'.format) - -df = pd.DataFrame([[15.22345676543234567]*6], columns=[1,2,3,4,5,6]) - -# Default float_format works: -print(df) # ✅ Columns display with 2 decimals - -default_fmt = '{:.2f}' -special_fmt = {1: '{:.1f}'} - -formats = { - col: special_fmt.get(col, default_fmt) - for col in df.columns -} - -styled = df.style.format(formats) -styled.to_html("styled.html") From 25256607ff73c50eee232a30c4c34b9d5555d612 Mon Sep 17 00:00:00 2001 From: arthurlw Date: Mon, 14 Apr 2025 11:43:16 -0700 Subject: [PATCH 5/5] Fixed docstring error --- pandas/core/groupby/groupby.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py index bb496c97f479f..2cb523d2f2f55 100644 --- a/pandas/core/groupby/groupby.py +++ b/pandas/core/groupby/groupby.py @@ -3889,13 +3889,14 @@ def ewm(self, *args, **kwargs) -> ExponentialMovingWindowGroupby: 5 B 60 >>> df.groupby("Class").ewm(com=0.5).mean() - Value - 0 10.000000 - 1 17.500000 - 2 26.153846 - 3 40.000000 - 4 47.500000 - 5 56.153846 + Value + Class + A 0 10.000000 + 1 17.500000 + 2 26.153846 + B 3 40.000000 + 4 47.500000 + 5 56.153846 """ from pandas.core.window import ExponentialMovingWindowGroupby