diff --git a/docs/api-reference/series.md b/docs/api-reference/series.md index e8572dda8..cbf4837bb 100644 --- a/docs/api-reference/series.md +++ b/docs/api-reference/series.md @@ -19,6 +19,7 @@ - diff - drop_nulls - dtype + - ewm_mean - fill_null - filter - gather_every diff --git a/mkdocs.yml b/mkdocs.yml index 46cb5335f..79cd57b53 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -112,3 +112,12 @@ markdown_extensions: - pymdownx.emoji: emoji_index: !!python/name:material.extensions.emoji.twemoji emoji_generator: !!python/name:material.extensions.emoji.to_svg +- pymdownx.arithmatex: + generic: true +extra_javascript: + - javascripts/katex.js + - https://unpkg.com/katex@0/dist/katex.min.js + - https://unpkg.com/katex@0/dist/contrib/auto-render.min.js + +extra_css: + - https://unpkg.com/katex@0/dist/katex.min.css \ No newline at end of file diff --git a/narwhals/_pandas_like/series.py b/narwhals/_pandas_like/series.py index 35df78e2f..466ddc28d 100644 --- a/narwhals/_pandas_like/series.py +++ b/narwhals/_pandas_like/series.py @@ -174,6 +174,24 @@ def dtype(self: Self) -> DType: self._native_series, self._dtypes, self._implementation ) + def ewm_mean( + self, + *, + com: float | None = None, + span: float | None = None, + half_life: float | None = None, + alpha: float | None = None, + adjust: bool = True, + min_periods: int = 1, + ignore_nulls: bool = False, + ) -> PandasLikeSeries: + ser = self._native_series + result = ser.ewm( + com, span, half_life, alpha, min_periods, adjust, ignore_na=ignore_nulls + ).mean() + + return self._from_native_series(result) + def scatter(self, indices: int | Sequence[int], values: Any) -> Self: if isinstance(values, self.__class__): # .copy() is necessary in some pre-2.2 versions of pandas to avoid diff --git a/narwhals/expr.py b/narwhals/expr.py index 6c2d28962..3846897bd 100644 --- a/narwhals/expr.py +++ b/narwhals/expr.py @@ -404,6 +404,29 @@ def all(self) -> Self: """ return self.__class__(lambda plx: self._call(plx).all()) + def ewm_mean( + self: Self, + *, + com: float | None = None, + span: float | None = None, + half_life: float | None = None, + alpha: float | None = None, + adjust: bool = True, + min_periods: int = 1, + ignore_nulls: bool = False, + ) -> Self: + return self.__class__( + lambda plx: self._call(plx).ewm_mean( + com=com, + span=span, + half_life=half_life, + alpha=alpha, + adjust=adjust, + min_periods=min_periods, + ignore_nulls=ignore_nulls, + ) + ) + def mean(self) -> Self: """ Get mean value. diff --git a/narwhals/series.py b/narwhals/series.py index 6f5223202..46ffe3ee1 100644 --- a/narwhals/series.py +++ b/narwhals/series.py @@ -383,6 +383,38 @@ def name(self) -> str: """ return self._compliant_series.name # type: ignore[no-any-return] + def ewm_mean( + self: Self, + *, + com: float | None = None, + span: float | None = None, + half_life: float | None = None, + alpha: float | None = None, + adjust: bool = True, + min_periods: int = 1, + ignore_nulls: bool = False, + ) -> Self: + """ + 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$ + + Examples + """ + return self._from_compliant_series( + self._compliant_series.ewm_mean( + com=com, + span=span, + half_life=half_life, + alpha=alpha, + adjust=adjust, + min_periods=min_periods, + ignore_nulls=ignore_nulls, + ) + ) + def cast( self, dtype: Any,