4343 # Pandas cumcount counts nulls while Polars does not
4444 # So, instead of using "cumcount" we use "cumsum" on notna() to get the same result
4545 "cum_count" : "cumsum" ,
46+ "rolling_sum" : "sum" ,
4647 "shift" : "shift" ,
4748 "rank" : "rank" ,
4849 "diff" : "diff" ,
@@ -64,6 +65,12 @@ def window_kwargs_to_pandas_equivalent(
6465 }
6566 elif function_name .startswith ("cum_" ): # Cumulative operation
6667 pandas_kwargs = {"skipna" : True }
68+ elif function_name .startswith ("rolling_" ): # Rolling operation
69+ pandas_kwargs = {
70+ "min_periods" : kwargs ["min_samples" ],
71+ "window" : kwargs ["window_size" ],
72+ "center" : kwargs ["center" ],
73+ }
6774 else : # e.g. std, var
6875 pandas_kwargs = kwargs
6976 return pandas_kwargs
@@ -487,11 +494,11 @@ def func(df: PandasLikeDataFrame) -> Sequence[PandasLikeSeries]:
487494 raise NotImplementedError (msg )
488495 else :
489496 function_name : str = re .sub (r"(\w+->)" , "" , self ._function_name )
490- if pandas_function_name : = WINDOW_FUNCTIONS_TO_PANDAS_EQUIVALENT .get (
491- function_name , AGGREGATIONS_TO_PANDAS_EQUIVALENT . get ( function_name , None )
492- ):
493- pass
494- else :
497+ pandas_function_name = WINDOW_FUNCTIONS_TO_PANDAS_EQUIVALENT .get (
498+ function_name ,
499+ AGGREGATIONS_TO_PANDAS_EQUIVALENT . get ( function_name ),
500+ )
501+ if pandas_function_name is None :
495502 msg = (
496503 f"Unsupported function: { function_name } in `over` context.\n \n "
497504 f"Supported functions are { ', ' .join (WINDOW_FUNCTIONS_TO_PANDAS_EQUIVALENT )} \n "
@@ -504,7 +511,6 @@ def func(df: PandasLikeDataFrame) -> Sequence[PandasLikeSeries]:
504511
505512 def func (df : PandasLikeDataFrame ) -> Sequence [PandasLikeSeries ]:
506513 output_names , aliases = evaluate_output_names_and_aliases (self , df , [])
507-
508514 if function_name == "cum_count" :
509515 plx = self .__narwhals_namespace__ ()
510516 df = df .with_columns (~ plx .col (* output_names ).is_null ())
@@ -527,9 +533,16 @@ def func(df: PandasLikeDataFrame) -> Sequence[PandasLikeSeries]:
527533 elif reverse :
528534 columns = list (set (partition_by ).union (output_names ))
529535 df = df [columns ][::- 1 ]
530- res_native = df ._native_frame .groupby (partition_by )[
531- list (output_names )
532- ].transform (pandas_function_name , ** pandas_kwargs )
536+ if function_name .startswith ("rolling" ):
537+ rolling = df ._native_frame .groupby (partition_by )[
538+ list (output_names )
539+ ].rolling (** pandas_kwargs )
540+ assert pandas_function_name is not None # help mypy # noqa: S101
541+ res_native = getattr (rolling , pandas_function_name )()
542+ else :
543+ res_native = df ._native_frame .groupby (partition_by )[
544+ list (output_names )
545+ ].transform (pandas_function_name , ** pandas_kwargs )
533546 result_frame = df ._from_native_frame (res_native ).rename (
534547 dict (zip (output_names , aliases ))
535548 )
@@ -650,25 +663,23 @@ def cum_prod(self: Self, *, reverse: bool) -> Self:
650663 )
651664
652665 def rolling_sum (
653- self : Self ,
654- window_size : int ,
655- * ,
656- min_samples : int | None ,
657- center : bool ,
666+ self : Self , window_size : int , * , min_samples : int , center : bool
658667 ) -> Self :
659668 return reuse_series_implementation (
660669 self ,
661670 "rolling_sum" ,
662- window_size = window_size ,
663- min_samples = min_samples ,
664- center = center ,
671+ call_kwargs = {
672+ "window_size" : window_size ,
673+ "min_samples" : min_samples ,
674+ "center" : center ,
675+ },
665676 )
666677
667678 def rolling_mean (
668679 self : Self ,
669680 window_size : int ,
670681 * ,
671- min_samples : int | None ,
682+ min_samples : int ,
672683 center : bool ,
673684 ) -> Self :
674685 return reuse_series_implementation (
@@ -683,7 +694,7 @@ def rolling_var(
683694 self : Self ,
684695 window_size : int ,
685696 * ,
686- min_samples : int | None ,
697+ min_samples : int ,
687698 center : bool ,
688699 ddof : int ,
689700 ) -> Self :
@@ -700,7 +711,7 @@ def rolling_std(
700711 self : Self ,
701712 window_size : int ,
702713 * ,
703- min_samples : int | None ,
714+ min_samples : int ,
704715 center : bool ,
705716 ddof : int ,
706717 ) -> Self :
0 commit comments