From a4b5bd754591ac6e89406ef65a32c585e977a0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= Date: Thu, 31 Oct 2024 15:10:21 +0100 Subject: [PATCH] expr docstring --- docs/api-reference/expr.md | 1 + narwhals/expr.py | 69 ++++++++++++++++++++++++++++++++++++++ narwhals/series.py | 29 ++++++++-------- 3 files changed, 84 insertions(+), 15 deletions(-) diff --git a/docs/api-reference/expr.md b/docs/api-reference/expr.md index 7188b2c36..092bce725 100644 --- a/docs/api-reference/expr.md +++ b/docs/api-reference/expr.md @@ -14,6 +14,7 @@ - cum_sum - diff - drop_nulls + - ewm_mean - fill_null - filter - gather_every diff --git a/narwhals/expr.py b/narwhals/expr.py index 3846897bd..1b9c689e5 100644 --- a/narwhals/expr.py +++ b/narwhals/expr.py @@ -415,6 +415,75 @@ def ewm_mean( min_periods: int = 1, ignore_nulls: bool = False, ) -> Self: + r""" + Compute exponentially-weighted moving average. + + Arguments: + com: Specify decay in terms of center of mass, $\gamma$, with
$\alpha = \frac{1}{1+\gamma}\forall\gamma\geq0$ + span: Specify decay in terms of span, $\theta$, with
$\alpha = \frac{2}{\theta + 1} \forall \theta \geq 1$ + half_life: Specify decay in terms of half-life, $\tau$, with
$\alpha = 1 - \exp \left\{ \frac{ -\ln(2) }{ \tau } \right\} \forall \tau > 0$ + alpha: Specify smoothing factor alpha directly, $0 < \alpha \leq 1$. + adjust: Divide by decaying adjustment factor in beginning periods to account for imbalance in relative weightings + + - When `adjust=True` (the default) the EW function is calculated + using weights $w_i = (1 - \alpha)^i$ + - When `adjust=False` the EW function is calculated recursively by + $$ + y_0=x_0 + $$ + $$ + y_t = (1 - \alpha)y_{t - 1} + \alpha x_t + $$ + min_periods: Minimum number of observations in window required to have a value, (otherwise result is null). + ignore_nulls: Ignore missing values when calculating weights. + + - When `ignore_nulls=False` (default), weights are based on absolute + positions. + For example, the weights of $x_0$ and $x_2$ used in + calculating the final weighted average of $[x_0, None, x_2]$ are + $(1-\alpha)^2$ and $1$ if `adjust=True`, and + $(1-\alpha)^2$ and $\alpha$ if `adjust=False`. + + - When `ignore_nulls=True`, weights are based + on relative positions. For example, the weights of + $x_0$ and $x_2$ used in calculating the final weighted + average of $[x_0, None, x_2]$ are + $1-\alpha$ and $1$ if `adjust=True`, + and $1-\alpha$ and $\alpha$ if `adjust=False`. + + Examples: + >>> import pandas as pd + >>> import polars as pl + >>> import narwhals as nw + >>> data = {"a": [1, 2, 3]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + + We define a library agnostic function: + + >>> @nw.narwhalify + ... def func(df): + ... return df.select(nw.col("a").ewm_mean(com=1, ignore_nulls=False)) + + We can then pass either pandas or Polars to `func`: + + + + + + >>> func(df_pl) # doctest: +NORMALIZE_WHITESPACE + shape: (3, 1) + ┌──────────┐ + │ a │ + │ --- │ + │ f64 │ + ╞══════════╡ + │ 1.0 │ + │ 1.666667 │ + │ 2.428571 │ + └──────────┘ + + """ return self.__class__( lambda plx: self._call(plx).ewm_mean( com=com, diff --git a/narwhals/series.py b/narwhals/series.py index 6f6f783b4..d5fa9b85d 100644 --- a/narwhals/series.py +++ b/narwhals/series.py @@ -394,42 +394,41 @@ def ewm_mean( min_periods: int = 1, ignore_nulls: bool = False, ) -> Self: - """ + r""" Compute exponentially-weighted moving average. Arguments: - com: Specify decay in terms of center of mass, $\\gamma$, with
$\\alpha = \\frac{1}{1+\\gamma}\\forall\\gamma\\geq0$ - span: Specify decay in terms of span, $\\theta$, with
$\\alpha = \\frac{2}{\\theta + 1} \\forall \\theta \\geq 1$ - half_life: Specify decay in terms of half-life, $\\tau$, with
$\\alpha = 1 - \\exp \\left\\{ \\frac{ -\\ln(2) }{ \\tau } \\right\\} \\forall \\tau > 0$ - alpha: Specify smoothing factor alpha directly, $0 < \\alpha \\leq 1$. + com: Specify decay in terms of center of mass, $\gamma$, with
$\alpha = \frac{1}{1+\gamma}\forall\gamma\geq0$ + span: Specify decay in terms of span, $\theta$, with
$\alpha = \frac{2}{\theta + 1} \forall \theta \geq 1$ + half_life: Specify decay in terms of half-life, $\tau$, with
$\alpha = 1 - \exp \left\{ \frac{ -\ln(2) }{ \tau } \right\} \forall \tau > 0$ + alpha: Specify smoothing factor alpha directly, $0 < \alpha \leq 1$. adjust: Divide by decaying adjustment factor in beginning periods to account for imbalance in relative weightings - When `adjust=True` (the default) the EW function is calculated - using weights $w_i = (1 - \\alpha)^i$ - - When `adjust=False` the EW function is calculated recursively by + using weights $w_i = (1 - \alpha)^i$ + - When `adjust=False` the EW function is calculated recursively by $$ y_0=x_0 $$ $$ - y_t = (1 - \\alpha)y_{t - 1} + \\alpha x_t + y_t = (1 - \alpha)y_{t - 1} + \alpha x_t $$ - min_periods: Minimum number of observations in window required to have a value - (otherwise result is null). + min_periods: Minimum number of observations in window required to have a value (otherwise result is null). ignore_nulls: Ignore missing values when calculating weights. - When `ignore_nulls=False` (default), weights are based on absolute positions. For example, the weights of $x_0$ and $x_2$ used in calculating the final weighted average of $[x_0, None, x_2]$ are - $(1-\\alpha)^2$ and $1$ if `adjust=True`, and - $(1-\\alpha)^2$ and $\\alpha$ if `adjust=False`. + $(1-\alpha)^2$ and $1$ if `adjust=True`, and + $(1-\alpha)^2$ and $\alpha$ if `adjust=False`. - When `ignore_nulls=True`, weights are based on relative positions. For example, the weights of $x_0$ and $x_2$ used in calculating the final weighted average of $[x_0, None, x_2]$ are - $1-\\alpha$ and $1$ if `adjust=True`, - and $1-\\alpha$ and $\\alpha$ if `adjust=False`. + $1-\alpha$ and $1$ if `adjust=True`, + and $1-\alpha$ and $\alpha$ if `adjust=False`. Examples: >>> import pandas as pd @@ -452,7 +451,7 @@ def ewm_mean( 1 1.666667 2 2.428571 Name: a, dtype: float64 - + >>> func(s_pl) # doctest: +NORMALIZE_WHITESPACE shape: (3,) Series: 'a' [f64]