|
37 | 37 | "rank": "rank", |
38 | 38 | "diff": "diff", |
39 | 39 | "fill_null": "fillna", |
| 40 | + "quantile": "quantile", |
| 41 | + "ewm_mean": "mean", |
40 | 42 | } |
41 | 43 |
|
42 | 44 |
|
@@ -74,6 +76,31 @@ def window_kwargs_to_pandas_equivalent( |
74 | 76 | assert "strategy" in kwargs # noqa: S101 |
75 | 77 | assert "limit" in kwargs # noqa: S101 |
76 | 78 | pandas_kwargs = {"strategy": kwargs["strategy"], "limit": kwargs["limit"]} |
| 79 | + elif function_name == "quantile": |
| 80 | + assert "quantile" in kwargs # noqa: S101 |
| 81 | + assert "interpolation" in kwargs # noqa: S101 |
| 82 | + pandas_kwargs = { |
| 83 | + "q": kwargs["quantile"], |
| 84 | + "interpolation": kwargs["interpolation"], |
| 85 | + } |
| 86 | + elif function_name.startswith("ewm_"): |
| 87 | + assert "com" in kwargs # noqa: S101 |
| 88 | + assert "span" in kwargs # noqa: S101 |
| 89 | + assert "half_life" in kwargs # noqa: S101 |
| 90 | + assert "alpha" in kwargs # noqa: S101 |
| 91 | + assert "adjust" in kwargs # noqa: S101 |
| 92 | + assert "min_samples" in kwargs # noqa: S101 |
| 93 | + assert "ignore_nulls" in kwargs # noqa: S101 |
| 94 | + |
| 95 | + pandas_kwargs = { |
| 96 | + "com": kwargs["com"], |
| 97 | + "span": kwargs["span"], |
| 98 | + "halflife": kwargs["half_life"], |
| 99 | + "alpha": kwargs["alpha"], |
| 100 | + "adjust": kwargs["adjust"], |
| 101 | + "min_periods": kwargs["min_samples"], |
| 102 | + "ignore_na": kwargs["ignore_nulls"], |
| 103 | + } |
77 | 104 | else: # sum, len, ... |
78 | 105 | pandas_kwargs = {} |
79 | 106 | return pandas_kwargs |
@@ -182,13 +209,15 @@ def ewm_mean( |
182 | 209 | ) -> Self: |
183 | 210 | return self._reuse_series( |
184 | 211 | "ewm_mean", |
185 | | - com=com, |
186 | | - span=span, |
187 | | - half_life=half_life, |
188 | | - alpha=alpha, |
189 | | - adjust=adjust, |
190 | | - min_samples=min_samples, |
191 | | - ignore_nulls=ignore_nulls, |
| 212 | + scalar_kwargs={ |
| 213 | + "com": com, |
| 214 | + "span": span, |
| 215 | + "half_life": half_life, |
| 216 | + "alpha": alpha, |
| 217 | + "adjust": adjust, |
| 218 | + "min_samples": min_samples, |
| 219 | + "ignore_nulls": ignore_nulls, |
| 220 | + }, |
192 | 221 | ) |
193 | 222 |
|
194 | 223 | def over( # noqa: C901, PLR0915 |
@@ -232,7 +261,7 @@ def func(df: PandasLikeDataFrame) -> Sequence[PandasLikeSeries]: |
232 | 261 | function_name, self._scalar_kwargs |
233 | 262 | ) |
234 | 263 |
|
235 | | - def func(df: PandasLikeDataFrame) -> Sequence[PandasLikeSeries]: # noqa: C901, PLR0912 |
| 264 | + def func(df: PandasLikeDataFrame) -> Sequence[PandasLikeSeries]: # noqa: C901, PLR0912, PLR0914, PLR0915 |
236 | 265 | output_names, aliases = evaluate_output_names_and_aliases(self, df, []) |
237 | 266 | if function_name == "cum_count": |
238 | 267 | plx = self.__narwhals_namespace__() |
@@ -268,6 +297,18 @@ def func(df: PandasLikeDataFrame) -> Sequence[PandasLikeSeries]: # noqa: C901, |
268 | 297 | ) |
269 | 298 | else: |
270 | 299 | res_native = getattr(rolling, pandas_function_name)() |
| 300 | + elif function_name.startswith("ewm"): |
| 301 | + if self._implementation.is_pandas() and ( |
| 302 | + backend_version := self._backend_version |
| 303 | + ) < (1, 2): # pragma: no cover |
| 304 | + msg = ( |
| 305 | + "Exponentially weighted calculation is not available in over " |
| 306 | + f"context for pandas versions older than 1.2.0, found {backend_version}." |
| 307 | + ) |
| 308 | + raise NotImplementedError(msg) |
| 309 | + ewm = grouped[list(output_names)].ewm(**pandas_kwargs) |
| 310 | + assert pandas_function_name is not None # help mypy # noqa: S101 |
| 311 | + res_native = getattr(ewm, pandas_function_name)() |
271 | 312 | elif function_name == "fill_null": |
272 | 313 | assert "strategy" in self._scalar_kwargs # noqa: S101 |
273 | 314 | assert "limit" in self._scalar_kwargs # noqa: S101 |
|
0 commit comments