Repository: narwhals-dev/narwhals
Pull request #1862 (2025-01-24 12:11:56)

test: skip Ibis tests if deps aren't installed, set defaults in `PandasLikeSeries.__array__` to fix cuDF is_in
<!--
# Thanks for contributing a pull request! 
## Please make sure you see our contribution guidelines: https://github.com/narwhals-dev/narwhals/blob/main/CONTRIBUTING.md
-->

## What type of PR is this? (check all applicable)

- [ ] 💾 Refactor
- [ ] ✨ Feature
- [ ] 🐛 Bug Fix
- [ ] 🔧 Optimization
- [ ] 📝 Documentation
- [ ] ✅ Test
- [ ] 🐳 Other

## Related issues

- Related issue #\<issue number\>
- Closes #\<issue number\>

## Checklist

- [ ] Code follows style guide (ruff)
- [ ] Tests added
- [ ] Documented the changes

## If you have comments or can explain your changes, please do so below



Patch:
diff --git a/narwhals/_arrow/expr.py b/narwhals/_arrow/expr.py
index 2d911c77..a79d68ac 100644
--- a/narwhals/_arrow/expr.py
+++ b/narwhals/_arrow/expr.py
@@ -472,14 +472,14 @@ class ArrowExpr(CompliantExpr[ArrowSeries]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
     ) -> Self:
         return reuse_series_implementation(
             self,
             "rolling_sum",
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
         )
 
@@ -487,14 +487,14 @@ class ArrowExpr(CompliantExpr[ArrowSeries]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
     ) -> Self:
         return reuse_series_implementation(
             self,
             "rolling_mean",
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
         )
 
@@ -502,7 +502,7 @@ class ArrowExpr(CompliantExpr[ArrowSeries]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
@@ -510,7 +510,7 @@ class ArrowExpr(CompliantExpr[ArrowSeries]):
             self,
             "rolling_var",
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
             ddof=ddof,
         )
@@ -519,7 +519,7 @@ class ArrowExpr(CompliantExpr[ArrowSeries]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
@@ -527,7 +527,7 @@ class ArrowExpr(CompliantExpr[ArrowSeries]):
             self,
             "rolling_std",
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
             ddof=ddof,
         )
diff --git a/narwhals/_arrow/series.py b/narwhals/_arrow/series.py
index fb29311e..6a6fe217 100644
--- a/narwhals/_arrow/series.py
+++ b/narwhals/_arrow/series.py
@@ -843,10 +843,10 @@ class ArrowSeries(CompliantSeries):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
     ) -> Self:
-        min_periods = min_periods if min_periods is not None else window_size
+        min_samples = min_samples if min_samples is not None else window_size
         padded_series, offset = pad_series(self, window_size=window_size, center=center)
 
         cum_sum = padded_series.cum_sum(reverse=False).fill_null(
@@ -866,7 +866,7 @@ class ArrowSeries(CompliantSeries):
 
         result = self._from_native_series(
             pc.if_else(
-                (count_in_window >= min_periods)._native_series,
+                (count_in_window >= min_samples)._native_series,
                 rolling_sum._native_series,
                 None,
             )
@@ -877,10 +877,10 @@ class ArrowSeries(CompliantSeries):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
     ) -> Self:
-        min_periods = min_periods if min_periods is not None else window_size
+        min_samples = min_samples if min_samples is not None else window_size
         padded_series, offset = pad_series(self, window_size=window_size, center=center)
 
         cum_sum = padded_series.cum_sum(reverse=False).fill_null(
@@ -901,7 +901,7 @@ class ArrowSeries(CompliantSeries):
         result = (
             self._from_native_series(
                 pc.if_else(
-                    (count_in_window >= min_periods)._native_series,
+                    (count_in_window >= min_samples)._native_series,
                     rolling_sum._native_series,
                     None,
                 )
@@ -914,11 +914,11 @@ class ArrowSeries(CompliantSeries):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
-        min_periods = min_periods if min_periods is not None else window_size
+        min_samples = min_samples if min_samples is not None else window_size
         padded_series, offset = pad_series(self, window_size=window_size, center=center)
 
         cum_sum = padded_series.cum_sum(reverse=False).fill_null(
@@ -950,7 +950,7 @@ class ArrowSeries(CompliantSeries):
 
         result = self._from_native_series(
             pc.if_else(
-                (count_in_window >= min_periods)._native_series,
+                (count_in_window >= min_samples)._native_series,
                 (rolling_sum_sq - (rolling_sum**2 / count_in_window))._native_series,
                 None,
             )
@@ -964,13 +964,13 @@ class ArrowSeries(CompliantSeries):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
         return (
             self.rolling_var(
-                window_size=window_size, min_periods=min_periods, center=center, ddof=ddof
+                window_size=window_size, min_samples=min_samples, center=center, ddof=ddof
             )
             ** 0.5
         )
diff --git a/narwhals/_pandas_like/expr.py b/narwhals/_pandas_like/expr.py
index 17852408..23021317 100644
--- a/narwhals/_pandas_like/expr.py
+++ b/narwhals/_pandas_like/expr.py
@@ -308,7 +308,7 @@ class PandasLikeExpr(CompliantExpr[PandasLikeSeries]):
         half_life: float | None,
         alpha: float | None,
         adjust: bool,
-        min_periods: int,
+        min_samples: int,
         ignore_nulls: bool,
     ) -> Self:
         return reuse_series_implementation(
@@ -319,7 +319,7 @@ class PandasLikeExpr(CompliantExpr[PandasLikeSeries]):
             half_life=half_life,
             alpha=alpha,
             adjust=adjust,
-            min_periods=min_periods,
+            min_samples=min_samples,
             ignore_nulls=ignore_nulls,
         )
 
@@ -563,14 +563,14 @@ class PandasLikeExpr(CompliantExpr[PandasLikeSeries]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
     ) -> Self:
         return reuse_series_implementation(
             self,
             "rolling_sum",
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
         )
 
@@ -578,14 +578,14 @@ class PandasLikeExpr(CompliantExpr[PandasLikeSeries]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
     ) -> Self:
         return reuse_series_implementation(
             self,
             "rolling_mean",
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
         )
 
@@ -593,7 +593,7 @@ class PandasLikeExpr(CompliantExpr[PandasLikeSeries]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
@@ -601,7 +601,7 @@ class PandasLikeExpr(CompliantExpr[PandasLikeSeries]):
             self,
             "rolling_var",
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
             ddof=ddof,
         )
@@ -610,7 +610,7 @@ class PandasLikeExpr(CompliantExpr[PandasLikeSeries]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
@@ -618,7 +618,7 @@ class PandasLikeExpr(CompliantExpr[PandasLikeSeries]):
             self,
             "rolling_std",
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
             ddof=ddof,
         )
diff --git a/narwhals/_pandas_like/series.py b/narwhals/_pandas_like/series.py
index f79aab1e..b847f3cd 100644
--- a/narwhals/_pandas_like/series.py
+++ b/narwhals/_pandas_like/series.py
@@ -191,13 +191,13 @@ class PandasLikeSeries(CompliantSeries):
         half_life: float | None,
         alpha: float | None,
         adjust: bool,
-        min_periods: int,
+        min_samples: int,
         ignore_nulls: bool,
     ) -> PandasLikeSeries:
         ser = self._native_series
         mask_na = ser.isna()
         if self._implementation is Implementation.CUDF:
-            if (min_periods == 0 and not ignore_nulls) or (not mask_na.any()):
+            if (min_samples == 0 and not ignore_nulls) or (not mask_na.any()):
                 result = ser.ewm(
                     com=com, span=span, halflife=half_life, alpha=alpha, adjust=adjust
                 ).mean()
@@ -209,7 +209,7 @@ class PandasLikeSeries(CompliantSeries):
                 raise NotImplementedError(msg)
         else:
             result = ser.ewm(
-                com, span, half_life, alpha, min_periods, adjust, ignore_na=ignore_nulls
+                com, span, half_life, alpha, min_samples, adjust, ignore_na=ignore_nulls
             ).mean()
         result[mask_na] = None
         return self._from_native_series(result)
@@ -294,6 +294,10 @@ class PandasLikeSeries(CompliantSeries):
 
     def is_in(self: Self, other: Any) -> PandasLikeSeries:
         ser = self._native_series
+        if isinstance(other, self.__class__):
+            # We can't use `broadcast_and_align` because we don't want to align here.
+            # `other` is just a sequence that all rows from `self` are checked against.
+            other = other._native_series
         res = ser.isin(other)
         return self._from_native_series(res)
 
@@ -921,11 +925,11 @@ class PandasLikeSeries(CompliantSeries):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
     ) -> Self:
         result = self._native_series.rolling(
-            window=window_size, min_periods=min_periods, center=center
+            window=window_size, min_periods=min_samples, center=center
         ).sum()
         return self._from_native_series(result)
 
@@ -933,11 +937,11 @@ class PandasLikeSeries(CompliantSeries):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
     ) -> Self:
         result = self._native_series.rolling(
-            window=window_size, min_periods=min_periods, center=center
+            window=window_size, min_periods=min_samples, center=center
         ).mean()
         return self._from_native_series(result)
 
@@ -945,12 +949,12 @@ class PandasLikeSeries(CompliantSeries):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
         result = self._native_series.rolling(
-            window=window_size, min_periods=min_periods, center=center
+            window=window_size, min_periods=min_samples, center=center
         ).var(ddof=ddof)
         return self._from_native_series(result)
 
@@ -958,12 +962,12 @@ class PandasLikeSeries(CompliantSeries):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
         result = self._native_series.rolling(
-            window=window_size, min_periods=min_periods, center=center
+            window=window_size, min_periods=min_samples, center=center
         ).std(ddof=ddof)
         return self._from_native_series(result)
 
diff --git a/narwhals/_polars/expr.py b/narwhals/_polars/expr.py
index ef0e90c2..98a692a6 100644
--- a/narwhals/_polars/expr.py
+++ b/narwhals/_polars/expr.py
@@ -58,19 +58,25 @@ class PolarsExpr:
         half_life: float | None,
         alpha: float | None,
         adjust: bool,
-        min_periods: int,
+        min_samples: int,
         ignore_nulls: bool,
     ) -> Self:
         expr = self._native_expr
 
+        extra_kwargs = (
+            {"min_periods": min_samples}
+            if self._backend_version < (1, 21, 0)
+            else {"min_samples": min_samples}
+        )
+
         native_expr = expr.ewm_mean(
             com=com,
             span=span,
             half_life=half_life,
             alpha=alpha,
             adjust=adjust,
-            min_periods=min_periods,
             ignore_nulls=ignore_nulls,
+            **extra_kwargs,
         )
         if self._backend_version < (1,):  # pragma: no cover
             import polars as pl
@@ -91,7 +97,7 @@ class PolarsExpr:
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
@@ -99,12 +105,17 @@ class PolarsExpr:
             msg = "`rolling_var` not implemented for polars older than 1.0"
             raise NotImplementedError(msg)
 
+        extra_kwargs = (
+            {"min_periods": min_samples}
+            if self._backend_version < (1, 21, 0)
+            else {"min_samples": min_samples}
+        )
         return self._from_native_expr(
             self._native_expr.rolling_var(
                 window_size=window_size,
-                min_periods=min_periods,
                 center=center,
                 ddof=ddof,
+                **extra_kwargs,  # type: ignore[arg-type]
             )
         )
 
@@ -112,20 +123,67 @@ class PolarsExpr:
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
         if self._backend_version < (1,):  # pragma: no cover
             msg = "`rolling_std` not implemented for polars older than 1.0"
             raise NotImplementedError(msg)
+        extra_kwargs = (
+            {"min_periods": min_samples}
+            if self._backend_version < (1, 21, 0)
+            else {"min_samples": min_samples}
+        )
 
         return self._from_native_expr(
             self._native_expr.rolling_std(
                 window_size=window_size,
-                min_periods=min_periods,
                 center=center,
                 ddof=ddof,
+                **extra_kwargs,  # type: ignore[arg-type]
+            )
+        )
+
+    def rolling_sum(
+        self: Self,
+        window_size: int,
+        *,
+        min_samples: int | None,
+        center: bool,
+    ) -> Self:
+        extra_kwargs = (
+            {"min_periods": min_samples}
+            if self._backend_version < (1, 21, 0)
+            else {"min_samples": min_samples}
+        )
+
+        return self._from_native_expr(
+            self._native_expr.rolling_sum(
+                window_size=window_size,
+                center=center,
+                **extra_kwargs,  # type: ignore[arg-type]
+            )
+        )
+
+    def rolling_mean(
+        self: Self,
+        window_size: int,
+        *,
+        min_samples: int | None,
+        center: bool,
+    ) -> Self:
+        extra_kwargs = (
+            {"min_periods": min_samples}
+            if self._backend_version < (1, 21, 0)
+            else {"min_samples": min_samples}
+        )
+
+        return self._from_native_expr(
+            self._native_expr.rolling_mean(
+                window_size=window_size,
+                center=center,
+                **extra_kwargs,  # type: ignore[arg-type]
             )
         )
 
diff --git a/narwhals/_polars/series.py b/narwhals/_polars/series.py
index fc8cfc8f..6a4d50d1 100644
--- a/narwhals/_polars/series.py
+++ b/narwhals/_polars/series.py
@@ -273,19 +273,25 @@ class PolarsSeries:
         half_life: float | None,
         alpha: float | None,
         adjust: bool,
-        min_periods: int,
+        min_samples: int,
         ignore_nulls: bool,
     ) -> Self:
         native_series = self._native_series
 
+        extra_kwargs = (
+            {"min_periods": min_samples}
+            if self._backend_version < (1, 21, 0)
+            else {"min_samples": min_samples}
+        )
+
         native_result = native_series.ewm_mean(
             com=com,
             span=span,
             half_life=half_life,
             alpha=alpha,
             adjust=adjust,
-            min_periods=min_periods,
             ignore_nulls=ignore_nulls,
+            **extra_kwargs,
         )
         if self._backend_version < (1,):  # pragma: no cover
             import polars as pl
@@ -302,7 +308,7 @@ class PolarsSeries:
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
@@ -310,12 +316,18 @@ class PolarsSeries:
             msg = "`rolling_var` not implemented for polars older than 1.0"
             raise NotImplementedError(msg)
 
+        extra_kwargs = (
+            {"min_periods": min_samples}
+            if self._backend_version < (1, 21, 0)
+            else {"min_samples": min_samples}
+        )
+
         return self._from_native_series(
             self._native_series.rolling_var(
                 window_size=window_size,
-                min_periods=min_periods,
                 center=center,
                 ddof=ddof,
+                **extra_kwargs,  # type: ignore[arg-type]
             )
         )
 
@@ -323,7 +335,7 @@ class PolarsSeries:
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None,
+        min_samples: int | None,
         center: bool,
         ddof: int,
     ) -> Self:
@@ -331,12 +343,60 @@ class PolarsSeries:
             msg = "`rolling_std` not implemented for polars older than 1.0"
             raise NotImplementedError(msg)
 
+        extra_kwargs = (
+            {"min_periods": min_samples}
+            if self._backend_version < (1, 21, 0)
+            else {"min_samples": min_samples}
+        )
+
         return self._from_native_series(
             self._native_series.rolling_std(
                 window_size=window_size,
-                min_periods=min_periods,
                 center=center,
                 ddof=ddof,
+                **extra_kwargs,  # type: ignore[arg-type]
+            )
+        )
+
+    def rolling_sum(
+        self: Self,
+        window_size: int,
+        *,
+        min_samples: int | None,
+        center: bool,
+    ) -> Self:
+        extra_kwargs = (
+            {"min_periods": min_samples}
+            if self._backend_version < (1, 21, 0)
+            else {"min_samples": min_samples}
+        )
+
+        return self._from_native_series(
+            self._native_series.rolling_sum(
+                window_size=window_size,
+                center=center,
+                **extra_kwargs,  # type: ignore[arg-type]
+            )
+        )
+
+    def rolling_mean(
+        self: Self,
+        window_size: int,
+        *,
+        min_samples: int | None,
+        center: bool,
+    ) -> Self:
+        extra_kwargs = (
+            {"min_periods": min_samples}
+            if self._backend_version < (1, 21, 0)
+            else {"min_samples": min_samples}
+        )
+
+        return self._from_native_series(
+            self._native_series.rolling_mean(
+                window_size=window_size,
+                center=center,
+                **extra_kwargs,  # type: ignore[arg-type]
             )
         )
 
diff --git a/narwhals/expr.py b/narwhals/expr.py
index 9e142c6d..5fbb4336 100644
--- a/narwhals/expr.py
+++ b/narwhals/expr.py
@@ -657,7 +657,7 @@ class Expr:
         half_life: float | None = None,
         alpha: float | None = None,
         adjust: bool = True,
-        min_periods: int = 1,
+        min_samples: int = 1,
         ignore_nulls: bool = False,
     ) -> Self:
         r"""Compute exponentially-weighted moving average.
@@ -682,7 +682,7 @@ class Expr:
                   $$
                   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_samples: 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
@@ -746,7 +746,7 @@ class Expr:
                 half_life=half_life,
                 alpha=alpha,
                 adjust=adjust,
-                min_periods=min_periods,
+                min_samples=min_samples,
                 ignore_nulls=ignore_nulls,
             ),
             is_order_dependent=self._is_order_dependent,
@@ -3874,7 +3874,7 @@ class Expr:
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
     ) -> Self:
         """Apply a rolling sum (moving sum) over the values.
@@ -3892,7 +3892,7 @@ class Expr:
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`
@@ -3918,7 +3918,7 @@ class Expr:
             >>> def agnostic_rolling_sum(df_native: IntoFrameT) -> IntoFrameT:
             ...     df = nw.from_native(df_native)
             ...     return df.with_columns(
-            ...         b=nw.col("a").rolling_sum(window_size=3, min_periods=1)
+            ...         b=nw.col("a").rolling_sum(window_size=3, min_samples=1)
             ...     ).to_native()
 
             We can then pass any supported library such as pandas, Polars, or
@@ -3952,14 +3952,14 @@ class Expr:
             a: [[1,2,null,4]]
             b: [[1,3,3,6]]
         """
-        window_size, min_periods = _validate_rolling_arguments(
-            window_size=window_size, min_periods=min_periods
+        window_size, min_samples = _validate_rolling_arguments(
+            window_size=window_size, min_samples=min_samples
         )
 
         return self.__class__(
             lambda plx: self._to_compliant_expr(plx).rolling_sum(
                 window_size=window_size,
-                min_periods=min_periods,
+                min_samples=min_samples,
                 center=center,
             ),
             is_order_dependent=True,
@@ -3971,7 +3971,7 @@ class Expr:
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
     ) -> Self:
         """Apply a rolling mean (moving mean) over the values.
@@ -3989,7 +3989,7 @@ class Expr:
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`
@@ -4015,7 +4015,7 @@ class Expr:
             >>> def agnostic_rolling_mean(df_native: IntoFrameT) -> IntoFrameT:
             ...     df = nw.from_native(df_native)
             ...     return df.with_columns(
-            ...         b=nw.col("a").rolling_mean(window_size=3, min_periods=1)
+            ...         b=nw.col("a").rolling_mean(window_size=3, min_samples=1)
             ...     ).to_native()
 
             We can then pass any supported library such as pandas, Polars, or
@@ -4049,14 +4049,14 @@ class Expr:
             a: [[1,2,null,4]]
             b: [[1,1.5,1.5,3]]
         """
-        window_size, min_periods = _validate_rolling_arguments(
-            window_size=window_size, min_periods=min_periods
+        window_size, min_samples = _validate_rolling_arguments(
+            window_size=window_size, min_samples=min_samples
         )
 
         return self.__class__(
             lambda plx: self._to_compliant_expr(plx).rolling_mean(
                 window_size=window_size,
-                min_periods=min_periods,
+                min_samples=min_samples,
                 center=center,
             ),
             is_order_dependent=True,
@@ -4068,7 +4068,7 @@ class Expr:
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
         ddof: int = 1,
     ) -> Self:
@@ -4087,7 +4087,7 @@ class Expr:
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`.
@@ -4114,7 +4114,7 @@ class Expr:
             >>> def agnostic_rolling_var(df_native: IntoFrameT) -> IntoFrameT:
             ...     df = nw.from_native(df_native)
             ...     return df.with_columns(
-            ...         b=nw.col("a").rolling_var(window_size=3, min_periods=1)
+            ...         b=nw.col("a").rolling_var(window_size=3, min_samples=1)
             ...     ).to_native()
 
             We can then pass any supported library such as pandas, Polars, or
@@ -4148,13 +4148,13 @@ class Expr:
             a: [[1,2,null,4]]
             b: [[nan,0.5,0.5,2]]
         """
-        window_size, min_periods = _validate_rolling_arguments(
-            window_size=window_size, min_periods=min_periods
+        window_size, min_samples = _validate_rolling_arguments(
+            window_size=window_size, min_samples=min_samples
         )
 
         return self.__class__(
             lambda plx: self._to_compliant_expr(plx).rolling_var(
-                window_size=window_size, min_periods=min_periods, center=center, ddof=ddof
+                window_size=window_size, min_samples=min_samples, center=center, ddof=ddof
             ),
             is_order_dependent=True,
             changes_length=self._changes_length,
@@ -4165,7 +4165,7 @@ class Expr:
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
         ddof: int = 1,
     ) -> Self:
@@ -4184,7 +4184,7 @@ class Expr:
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`.
@@ -4211,7 +4211,7 @@ class Expr:
             >>> def agnostic_rolling_std(df_native: IntoFrameT) -> IntoFrameT:
             ...     df = nw.from_native(df_native)
             ...     return df.with_columns(
-            ...         b=nw.col("a").rolling_std(window_size=3, min_periods=1)
+            ...         b=nw.col("a").rolling_std(window_size=3, min_samples=1)
             ...     ).to_native()
 
             We can then pass any supported library such as pandas, Polars, or
@@ -4245,14 +4245,14 @@ class Expr:
             a: [[1,2,null,4]]
             b: [[nan,0.7071067811865476,0.7071067811865476,1.4142135623730951]]
         """
-        window_size, min_periods = _validate_rolling_arguments(
-            window_size=window_size, min_periods=min_periods
+        window_size, min_samples = _validate_rolling_arguments(
+            window_size=window_size, min_samples=min_samples
         )
 
         return self.__class__(
             lambda plx: self._to_compliant_expr(plx).rolling_std(
                 window_size=window_size,
-                min_periods=min_periods,
+                min_samples=min_samples,
                 center=center,
                 ddof=ddof,
             ),
diff --git a/narwhals/series.py b/narwhals/series.py
index 7b82e39e..c71f9908 100644
--- a/narwhals/series.py
+++ b/narwhals/series.py
@@ -597,7 +597,7 @@ class Series(Generic[IntoSeriesT]):
         half_life: float | None = None,
         alpha: float | None = None,
         adjust: bool = True,
-        min_periods: int = 1,
+        min_samples: int = 1,
         ignore_nulls: bool = False,
     ) -> Self:
         r"""Compute exponentially-weighted moving average.
@@ -622,7 +622,7 @@ class Series(Generic[IntoSeriesT]):
                   $$
                   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_samples: 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
@@ -682,7 +682,7 @@ class Series(Generic[IntoSeriesT]):
                 half_life=half_life,
                 alpha=alpha,
                 adjust=adjust,
-                min_periods=min_periods,
+                min_samples=min_samples,
                 ignore_nulls=ignore_nulls,
             )
         )
@@ -4423,7 +4423,7 @@ class Series(Generic[IntoSeriesT]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
     ) -> Self:
         """Apply a rolling sum (moving sum) over the values.
@@ -4441,7 +4441,7 @@ class Series(Generic[IntoSeriesT]):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`
@@ -4499,8 +4499,8 @@ class Series(Generic[IntoSeriesT]):
               ]
             ]
         """
-        window_size, min_periods = _validate_rolling_arguments(
-            window_size=window_size, min_periods=min_periods
+        window_size, min_samples = _validate_rolling_arguments(
+            window_size=window_size, min_samples=min_samples
         )
 
         if len(self) == 0:  # pragma: no cover
@@ -4509,7 +4509,7 @@ class Series(Generic[IntoSeriesT]):
         return self._from_compliant_series(
             self._compliant_series.rolling_sum(
                 window_size=window_size,
-                min_periods=min_periods,
+                min_samples=min_samples,
                 center=center,
             )
         )
@@ -4518,7 +4518,7 @@ class Series(Generic[IntoSeriesT]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
     ) -> Self:
         """Apply a rolling mean (moving mean) over the values.
@@ -4536,7 +4536,7 @@ class Series(Generic[IntoSeriesT]):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`
@@ -4594,8 +4594,8 @@ class Series(Generic[IntoSeriesT]):
               ]
             ]
         """
-        window_size, min_periods = _validate_rolling_arguments(
-            window_size=window_size, min_periods=min_periods
+        window_size, min_samples = _validate_rolling_arguments(
+            window_size=window_size, min_samples=min_samples
         )
 
         if len(self) == 0:  # pragma: no cover
@@ -4604,7 +4604,7 @@ class Series(Generic[IntoSeriesT]):
         return self._from_compliant_series(
             self._compliant_series.rolling_mean(
                 window_size=window_size,
-                min_periods=min_periods,
+                min_samples=min_samples,
                 center=center,
             )
         )
@@ -4613,7 +4613,7 @@ class Series(Generic[IntoSeriesT]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
         ddof: int = 1,
     ) -> Self:
@@ -4632,7 +4632,7 @@ class Series(Generic[IntoSeriesT]):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`.
@@ -4658,7 +4658,7 @@ class Series(Generic[IntoSeriesT]):
 
             >>> def agnostic_rolling_var(s_native: IntoSeriesT) -> IntoSeriesT:
             ...     s = nw.from_native(s_native, series_only=True)
-            ...     return s.rolling_var(window_size=2, min_periods=1).to_native()
+            ...     return s.rolling_var(window_size=2, min_samples=1).to_native()
 
             We can then pass any supported library such as pandas, Polars, or
             PyArrow to `agnostic_rolling_var`:
@@ -4691,8 +4691,8 @@ class Series(Generic[IntoSeriesT]):
               ]
             ]
         """
-        window_size, min_periods = _validate_rolling_arguments(
-            window_size=window_size, min_periods=min_periods
+        window_size, min_samples = _validate_rolling_arguments(
+            window_size=window_size, min_samples=min_samples
         )
 
         if len(self) == 0:  # pragma: no cover
@@ -4700,7 +4700,7 @@ class Series(Generic[IntoSeriesT]):
 
         return self._from_compliant_series(
             self._compliant_series.rolling_var(
-                window_size=window_size, min_periods=min_periods, center=center, ddof=ddof
+                window_size=window_size, min_samples=min_samples, center=center, ddof=ddof
             )
         )
 
@@ -4708,7 +4708,7 @@ class Series(Generic[IntoSeriesT]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
         ddof: int = 1,
     ) -> Self:
@@ -4727,7 +4727,7 @@ class Series(Generic[IntoSeriesT]):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`.
@@ -4753,7 +4753,7 @@ class Series(Generic[IntoSeriesT]):
 
             >>> def agnostic_rolling_std(s_native: IntoSeriesT) -> IntoSeriesT:
             ...     s = nw.from_native(s_native, series_only=True)
-            ...     return s.rolling_std(window_size=2, min_periods=1).to_native()
+            ...     return s.rolling_std(window_size=2, min_samples=1).to_native()
 
             We can then pass any supported library such as pandas, Polars, or
             PyArrow to `agnostic_rolling_std`:
@@ -4786,8 +4786,8 @@ class Series(Generic[IntoSeriesT]):
               ]
             ]
         """
-        window_size, min_periods = _validate_rolling_arguments(
-            window_size=window_size, min_periods=min_periods
+        window_size, min_samples = _validate_rolling_arguments(
+            window_size=window_size, min_samples=min_samples
         )
 
         if len(self) == 0:  # pragma: no cover
@@ -4795,7 +4795,7 @@ class Series(Generic[IntoSeriesT]):
 
         return self._from_compliant_series(
             self._compliant_series.rolling_std(
-                window_size=window_size, min_periods=min_periods, center=center, ddof=ddof
+                window_size=window_size, min_samples=min_samples, center=center, ddof=ddof
             )
         )
 
diff --git a/narwhals/stable/v1/__init__.py b/narwhals/stable/v1/__init__.py
index abafc412..ffd6fc43 100644
--- a/narwhals/stable/v1/__init__.py
+++ b/narwhals/stable/v1/__init__.py
@@ -371,7 +371,7 @@ class Series(NwSeries[Any]):
         half_life: float | None = None,
         alpha: float | None = None,
         adjust: bool = True,
-        min_periods: int = 1,
+        min_samples: int = 1,
         ignore_nulls: bool = False,
     ) -> Self:
         r"""Compute exponentially-weighted moving average.
@@ -396,7 +396,7 @@ class Series(NwSeries[Any]):
                   $$
                   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_samples: 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
@@ -429,7 +429,7 @@ class Series(NwSeries[Any]):
             half_life=half_life,
             alpha=alpha,
             adjust=adjust,
-            min_periods=min_periods,
+            min_samples=min_samples,
             ignore_nulls=ignore_nulls,
         )
 
@@ -437,7 +437,7 @@ class Series(NwSeries[Any]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
     ) -> Self:
         """Apply a rolling sum (moving sum) over the values.
@@ -455,7 +455,7 @@ class Series(NwSeries[Any]):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`
@@ -474,7 +474,7 @@ class Series(NwSeries[Any]):
         warn(message=msg, category=NarwhalsUnstableWarning, stacklevel=find_stacklevel())
         return super().rolling_sum(
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
         )
 
@@ -482,7 +482,7 @@ class Series(NwSeries[Any]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
     ) -> Self:
         """Apply a rolling mean (moving mean) over the values.
@@ -500,7 +500,7 @@ class Series(NwSeries[Any]):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`
@@ -519,7 +519,7 @@ class Series(NwSeries[Any]):
         warn(message=msg, category=NarwhalsUnstableWarning, stacklevel=find_stacklevel())
         return super().rolling_mean(
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
         )
 
@@ -527,7 +527,7 @@ class Series(NwSeries[Any]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
         ddof: int = 1,
     ) -> Self:
@@ -546,7 +546,7 @@ class Series(NwSeries[Any]):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`.
@@ -566,7 +566,7 @@ class Series(NwSeries[Any]):
         warn(message=msg, category=NarwhalsUnstableWarning, stacklevel=find_stacklevel())
         return super().rolling_var(
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
             ddof=ddof,
         )
@@ -575,7 +575,7 @@ class Series(NwSeries[Any]):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
         ddof: int = 1,
     ) -> Self:
@@ -594,7 +594,7 @@ class Series(NwSeries[Any]):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`.
@@ -614,7 +614,7 @@ class Series(NwSeries[Any]):
         warn(message=msg, category=NarwhalsUnstableWarning, stacklevel=find_stacklevel())
         return super().rolling_std(
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
             ddof=ddof,
         )
@@ -632,7 +632,7 @@ class Expr(NwExpr):
         half_life: float | None = None,
         alpha: float | None = None,
         adjust: bool = True,
-        min_periods: int = 1,
+        min_samples: int = 1,
         ignore_nulls: bool = False,
     ) -> Self:
         r"""Compute exponentially-weighted moving average.
@@ -657,7 +657,7 @@ class Expr(NwExpr):
                   $$
                   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_samples: 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
@@ -690,7 +690,7 @@ class Expr(NwExpr):
             half_life=half_life,
             alpha=alpha,
             adjust=adjust,
-            min_periods=min_periods,
+            min_samples=min_samples,
             ignore_nulls=ignore_nulls,
         )
 
@@ -698,7 +698,7 @@ class Expr(NwExpr):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
     ) -> Self:
         """Apply a rolling sum (moving sum) over the values.
@@ -716,7 +716,7 @@ class Expr(NwExpr):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`
@@ -735,7 +735,7 @@ class Expr(NwExpr):
         warn(message=msg, category=NarwhalsUnstableWarning, stacklevel=find_stacklevel())
         return super().rolling_sum(
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
         )
 
@@ -743,7 +743,7 @@ class Expr(NwExpr):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
     ) -> Self:
         """Apply a rolling mean (moving mean) over the values.
@@ -761,7 +761,7 @@ class Expr(NwExpr):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`
@@ -780,7 +780,7 @@ class Expr(NwExpr):
         warn(message=msg, category=NarwhalsUnstableWarning, stacklevel=find_stacklevel())
         return super().rolling_mean(
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
         )
 
@@ -788,7 +788,7 @@ class Expr(NwExpr):
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
         ddof: int = 1,
     ) -> Self:
@@ -807,7 +807,7 @@ class Expr(NwExpr):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`.
@@ -826,14 +826,14 @@ class Expr(NwExpr):
         )
         warn(message=msg, category=NarwhalsUnstableWarning, stacklevel=find_stacklevel())
         return super().rolling_var(
-            window_size=window_size, min_periods=min_periods, center=center, ddof=ddof
+            window_size=window_size, min_samples=min_samples, center=center, ddof=ddof
         )
 
     def rolling_std(
         self: Self,
         window_size: int,
         *,
-        min_periods: int | None = None,
+        min_samples: int | None = None,
         center: bool = False,
         ddof: int = 1,
     ) -> Self:
@@ -852,7 +852,7 @@ class Expr(NwExpr):
         Arguments:
             window_size: The length of the window in number of elements. It must be a
                 strictly positive integer.
-            min_periods: The number of values in the window that should be non-null before
+            min_samples: The number of values in the window that should be non-null before
                 computing a result. If set to `None` (default), it will be set equal to
                 `window_size`. If provided, it must be a strictly positive integer, and
                 less than or equal to `window_size`
@@ -872,7 +872,7 @@ class Expr(NwExpr):
         warn(message=msg, category=NarwhalsUnstableWarning, stacklevel=find_stacklevel())
         return super().rolling_std(
             window_size=window_size,
-            min_periods=min_periods,
+            min_samples=min_samples,
             center=center,
             ddof=ddof,
         )
diff --git a/narwhals/utils.py b/narwhals/utils.py
index e8365b99..752f7150 100644
--- a/narwhals/utils.py
+++ b/narwhals/utils.py
@@ -996,7 +996,7 @@ def validate_strict_and_pass_though(
 
 
 def _validate_rolling_arguments(
-    window_size: int, min_periods: int | None
+    window_size: int, min_samples: int | None
 ) -> tuple[int, int]:
     if window_size < 1:
         msg = "window_size must be greater or equal than 1"
@@ -1010,25 +1010,25 @@ def _validate_rolling_arguments(
         )
         raise TypeError(msg)
 
-    if min_periods is not None:
-        if min_periods < 1:
-            msg = "min_periods must be greater or equal than 1"
+    if min_samples is not None:
+        if min_samples < 1:
+            msg = "min_samples must be greater or equal than 1"
             raise ValueError(msg)
 
-        if not isinstance(min_periods, int):
-            _type = min_periods.__class__.__name__
+        if not isinstance(min_samples, int):
+            _type = min_samples.__class__.__name__
             msg = (
-                f"argument 'min_periods': '{_type}' object cannot be "
+                f"argument 'min_samples': '{_type}' object cannot be "
                 "interpreted as an integer"
             )
             raise TypeError(msg)
-        if min_periods > window_size:
-            msg = "`min_periods` must be less or equal than `window_size`"
+        if min_samples > window_size:
+            msg = "`min_samples` must be less or equal than `window_size`"
             raise InvalidOperationError(msg)
     else:
-        min_periods = window_size
+        min_samples = window_size
 
-    return window_size, min_periods
+    return window_size, min_samples
 
 
 def generate_repr(header: str, native_repr: str) -> str:


Test patch:
diff --git a/tests/expr_and_series/ewm_test.py b/tests/expr_and_series/ewm_test.py
index 2463809e..34941c6d 100644
--- a/tests/expr_and_series/ewm_test.py
+++ b/tests/expr_and_series/ewm_test.py
@@ -153,7 +153,7 @@ def test_ewm_mean_params(
     expected = {"a": [None, 4.0, 3.4285714285714284]}
     assert_equal_data(
         df.select(
-            nw.col("a").ewm_mean(alpha=0.5, adjust=True, min_periods=2, ignore_nulls=True)
+            nw.col("a").ewm_mean(alpha=0.5, adjust=True, min_samples=2, ignore_nulls=True)
         ),
         expected,
     )
diff --git a/tests/expr_and_series/rolling_mean_test.py b/tests/expr_and_series/rolling_mean_test.py
index b91ecb27..5d69639c 100644
--- a/tests/expr_and_series/rolling_mean_test.py
+++ b/tests/expr_and_series/rolling_mean_test.py
@@ -19,19 +19,19 @@ data = {"a": [None, 1, 2, None, 4, 6, 11]}
 kwargs_and_expected: dict[str, dict[str, Any]] = {
     "x1": {"kwargs": {"window_size": 3}, "expected": [None] * 6 + [7.0]},
     "x2": {
-        "kwargs": {"window_size": 3, "min_periods": 1},
+        "kwargs": {"window_size": 3, "min_samples": 1},
         "expected": [None, 1.0, 1.5, 1.5, 3.0, 5.0, 7.0],
     },
     "x3": {
-        "kwargs": {"window_size": 2, "min_periods": 1},
+        "kwargs": {"window_size": 2, "min_samples": 1},
         "expected": [None, 1.0, 1.5, 2.0, 4.0, 5.0, 8.5],
     },
     "x4": {
-        "kwargs": {"window_size": 5, "min_periods": 1, "center": True},
+        "kwargs": {"window_size": 5, "min_samples": 1, "center": True},
         "expected": [1.5, 1.5, 7 / 3, 3.25, 5.75, 7.0, 7.0],
     },
     "x5": {
-        "kwargs": {"window_size": 4, "min_periods": 1, "center": True},
+        "kwargs": {"window_size": 4, "min_samples": 1, "center": True},
         "expected": [1.0, 1.5, 1.5, 7 / 3, 4.0, 7.0, 7.0],
     },
 }
@@ -81,17 +81,17 @@ def test_rolling_mean_hypothesis(center: bool, values: list[float]) -> None:  #
     s = pd.Series(values)
     n_missing = random.randint(0, len(s) - 1)  # noqa: S311
     window_size = random.randint(1, len(s))  # noqa: S311
-    min_periods = random.randint(1, window_size)  # noqa: S311
+    min_samples = random.randint(1, window_size)  # noqa: S311
     mask = random.sample(range(len(s)), n_missing)
     s[mask] = None
     df = pd.DataFrame({"a": s})
     expected = (
-        s.rolling(window=window_size, center=center, min_periods=min_periods)
+        s.rolling(window=window_size, center=center, min_periods=min_samples)
         .mean()
         .to_frame("a")
     )
     result = nw.from_native(pa.Table.from_pandas(df)).select(
-        nw.col("a").rolling_mean(window_size, center=center, min_periods=min_periods)
+        nw.col("a").rolling_mean(window_size, center=center, min_samples=min_samples)
     )
     expected_dict = nw.from_native(expected, eager_only=True).to_dict(as_series=False)
     assert_equal_data(result, expected_dict)
diff --git a/tests/expr_and_series/rolling_std_test.py b/tests/expr_and_series/rolling_std_test.py
index 1b9f4998..8d47ba22 100644
--- a/tests/expr_and_series/rolling_std_test.py
+++ b/tests/expr_and_series/rolling_std_test.py
@@ -23,7 +23,7 @@ kwargs_and_expected = (
     },
     {
         "name": "x2",
-        "kwargs": {"window_size": 3, "min_periods": 1},
+        "kwargs": {"window_size": 3, "min_samples": 1},
         "expected": [
             sqrt(x) if x is not None else x
             for x in [None, 0.5, 1 / 3, 1.0, 4 / 3, 7 / 3, 3]
@@ -31,14 +31,14 @@ kwargs_and_expected = (
     },
     {
         "name": "x3",
-        "kwargs": {"window_size": 2, "min_periods": 1},
+        "kwargs": {"window_size": 2, "min_samples": 1},
         "expected": [
             sqrt(x) if x is not None else x for x in [None, 0.5, 0.5, 2.0, 2.0, 4.5, 4.5]
         ],
     },
     {
         "name": "x4",
-        "kwargs": {"window_size": 5, "min_periods": 1, "center": True},
+        "kwargs": {"window_size": 5, "min_samples": 1, "center": True},
         "expected": [
             sqrt(x) if x is not None else x
             for x in [1 / 3, 11 / 12, 4 / 5, 17 / 10, 2.0, 2.25, 3]
@@ -46,7 +46,7 @@ kwargs_and_expected = (
     },
     {
         "name": "x5",
-        "kwargs": {"window_size": 4, "min_periods": 1, "center": True},
+        "kwargs": {"window_size": 4, "min_samples": 1, "center": True},
         "expected": [
             sqrt(x) if x is not None else x
             for x in [0.5, 1 / 3, 11 / 12, 11 / 12, 2.25, 2.25, 3]
diff --git a/tests/expr_and_series/rolling_sum_test.py b/tests/expr_and_series/rolling_sum_test.py
index f6378605..59872bef 100644
--- a/tests/expr_and_series/rolling_sum_test.py
+++ b/tests/expr_and_series/rolling_sum_test.py
@@ -20,19 +20,19 @@ data = {"a": [None, 1, 2, None, 4, 6, 11]}
 kwargs_and_expected: dict[str, dict[str, Any]] = {
     "x1": {"kwargs": {"window_size": 3}, "expected": [None] * 6 + [21]},
     "x2": {
-        "kwargs": {"window_size": 3, "min_periods": 1},
+        "kwargs": {"window_size": 3, "min_samples": 1},
         "expected": [None, 1.0, 3.0, 3.0, 6.0, 10.0, 21.0],
     },
     "x3": {
-        "kwargs": {"window_size": 2, "min_periods": 1},
+        "kwargs": {"window_size": 2, "min_samples": 1},
         "expected": [None, 1.0, 3.0, 2.0, 4.0, 10.0, 17.0],
     },
     "x4": {
-        "kwargs": {"window_size": 5, "min_periods": 1, "center": True},
+        "kwargs": {"window_size": 5, "min_samples": 1, "center": True},
         "expected": [3.0, 3.0, 7.0, 13.0, 23.0, 21.0, 21.0],
     },
     "x5": {
-        "kwargs": {"window_size": 4, "min_periods": 1, "center": True},
+        "kwargs": {"window_size": 4, "min_samples": 1, "center": True},
         "expected": [1.0, 3.0, 3.0, 7.0, 12.0, 21.0, 21.0],
     },
 }
@@ -74,7 +74,7 @@ def test_rolling_sum_series(constructor_eager: ConstructorEager) -> None:
     "ignore:`Expr.rolling_sum` is being called from the stable API although considered an unstable feature."
 )
 @pytest.mark.parametrize(
-    ("window_size", "min_periods", "context"),
+    ("window_size", "min_samples", "context"),
     [
         (
             -1,
@@ -95,7 +95,7 @@ def test_rolling_sum_series(constructor_eager: ConstructorEager) -> None:
             2,
             -1,
             pytest.raises(
-                ValueError, match="min_periods must be greater or equal than 1"
+                ValueError, match="min_samples must be greater or equal than 1"
             ),
         ),
         (
@@ -103,7 +103,7 @@ def test_rolling_sum_series(constructor_eager: ConstructorEager) -> None:
             4.2,
             pytest.raises(
                 TypeError,
-                match="argument 'min_periods': 'float' object cannot be interpreted as an integer",
+                match="argument 'min_samples': 'float' object cannot be interpreted as an integer",
             ),
         ),
         (
@@ -111,7 +111,7 @@ def test_rolling_sum_series(constructor_eager: ConstructorEager) -> None:
             2,
             pytest.raises(
                 InvalidOperationError,
-                match="`min_periods` must be less or equal than `window_size`",
+                match="`min_samples` must be less or equal than `window_size`",
             ),
         ),
     ],
@@ -119,14 +119,14 @@ def test_rolling_sum_series(constructor_eager: ConstructorEager) -> None:
 def test_rolling_sum_expr_invalid_params(
     constructor_eager: ConstructorEager,
     window_size: int,
-    min_periods: int | None,
+    min_samples: int | None,
     context: Any,
 ) -> None:
     df = nw.from_native(constructor_eager(data))
 
     with context:
         df.select(
-            nw.col("a").rolling_sum(window_size=window_size, min_periods=min_periods)
+            nw.col("a").rolling_sum(window_size=window_size, min_samples=min_samples)
         )
 
 
@@ -134,7 +134,7 @@ def test_rolling_sum_expr_invalid_params(
     "ignore:`Series.rolling_sum` is being called from the stable API although considered an unstable feature."
 )
 @pytest.mark.parametrize(
-    ("window_size", "min_periods", "context"),
+    ("window_size", "min_samples", "context"),
     [
         (
             -1,
@@ -155,7 +155,7 @@ def test_rolling_sum_expr_invalid_params(
             2,
             -1,
             pytest.raises(
-                ValueError, match="min_periods must be greater or equal than 1"
+                ValueError, match="min_samples must be greater or equal than 1"
             ),
         ),
         (
@@ -163,7 +163,7 @@ def test_rolling_sum_expr_invalid_params(
             4.2,
             pytest.raises(
                 TypeError,
-                match="argument 'min_periods': 'float' object cannot be interpreted as an integer",
+                match="argument 'min_samples': 'float' object cannot be interpreted as an integer",
             ),
         ),
         (
@@ -171,7 +171,7 @@ def test_rolling_sum_expr_invalid_params(
             2,
             pytest.raises(
                 InvalidOperationError,
-                match="`min_periods` must be less or equal than `window_size`",
+                match="`min_samples` must be less or equal than `window_size`",
             ),
         ),
     ],
@@ -179,13 +179,13 @@ def test_rolling_sum_expr_invalid_params(
 def test_rolling_sum_series_invalid_params(
     constructor_eager: ConstructorEager,
     window_size: int,
-    min_periods: int | None,
+    min_samples: int | None,
     context: Any,
 ) -> None:
     df = nw.from_native(constructor_eager(data))
 
     with context:
-        df["a"].rolling_sum(window_size=window_size, min_periods=min_periods)
+        df["a"].rolling_sum(window_size=window_size, min_samples=min_samples)
 
 
 @given(  # type: ignore[misc]
@@ -200,17 +200,17 @@ def test_rolling_sum_hypothesis(center: bool, values: list[float]) -> None:  # n
     s = pd.Series(values)
     n_missing = random.randint(0, len(s) - 1)  # noqa: S311
     window_size = random.randint(1, len(s))  # noqa: S311
-    min_periods = random.randint(1, window_size)  # noqa: S311
+    min_samples = random.randint(1, window_size)  # noqa: S311
     mask = random.sample(range(len(s)), n_missing)
     s[mask] = None
     df = pd.DataFrame({"a": s})
     expected = (
-        s.rolling(window=window_size, center=center, min_periods=min_periods)
+        s.rolling(window=window_size, center=center, min_periods=min_samples)
         .sum()
         .to_frame("a")
     )
     result = nw.from_native(pa.Table.from_pandas(df)).select(
-        nw.col("a").rolling_sum(window_size, center=center, min_periods=min_periods)
+        nw.col("a").rolling_sum(window_size, center=center, min_samples=min_samples)
     )
     expected_dict = nw.from_native(expected, eager_only=True).to_dict(as_series=False)
     assert_equal_data(result, expected_dict)
diff --git a/tests/expr_and_series/rolling_var_test.py b/tests/expr_and_series/rolling_var_test.py
index 3e5bb0c9..5eeda490 100644
--- a/tests/expr_and_series/rolling_var_test.py
+++ b/tests/expr_and_series/rolling_var_test.py
@@ -26,22 +26,22 @@ kwargs_and_expected = (
     },
     {
         "name": "x2",
-        "kwargs": {"window_size": 3, "min_periods": 1},
+        "kwargs": {"window_size": 3, "min_samples": 1},
         "expected": [None, 0.5, 1 / 3, 1.0, 4 / 3, 7 / 3, 3],
     },
     {
         "name": "x3",
-        "kwargs": {"window_size": 2, "min_periods": 1},
+        "kwargs": {"window_size": 2, "min_samples": 1},
         "expected": [None, 0.5, 0.5, 2.0, 2.0, 4.5, 4.5],
     },
     {
         "name": "x4",
-        "kwargs": {"window_size": 5, "min_periods": 1, "center": True},
+        "kwargs": {"window_size": 5, "min_samples": 1, "center": True},
         "expected": [1 / 3, 11 / 12, 4 / 5, 17 / 10, 2.0, 2.25, 3],
     },
     {
         "name": "x5",
-        "kwargs": {"window_size": 4, "min_periods": 1, "center": True},
+        "kwargs": {"window_size": 4, "min_samples": 1, "center": True},
         "expected": [0.5, 1 / 3, 11 / 12, 11 / 12, 2.25, 2.25, 3],
     },
     {
@@ -110,21 +110,21 @@ def test_rolling_var_series(
 def test_rolling_var_hypothesis(center: bool, values: list[float]) -> None:  # noqa: FBT001
     s = pd.Series(values)
     window_size = random.randint(2, len(s))  # noqa: S311
-    min_periods = random.randint(2, window_size)  # noqa: S311
-    ddof = random.randint(0, min_periods - 1)  # noqa: S311
+    min_samples = random.randint(2, window_size)  # noqa: S311
+    ddof = random.randint(0, min_samples - 1)  # noqa: S311
     mask = random.sample(range(len(s)), 2)
 
     s[mask] = None
     df = pd.DataFrame({"a": s})
     expected = (
-        s.rolling(window=window_size, center=center, min_periods=min_periods)
+        s.rolling(window=window_size, center=center, min_periods=min_samples)
         .var(ddof=ddof)
         .to_frame("a")
     )
 
     result = nw.from_native(pa.Table.from_pandas(df)).select(
         nw.col("a").rolling_var(
-            window_size, center=center, min_periods=min_periods, ddof=ddof
+            window_size, center=center, min_samples=min_samples, ddof=ddof
         )
     )
     expected_dict = nw.from_native(expected, eager_only=True).to_dict(as_series=False)
@@ -132,7 +132,7 @@ def test_rolling_var_hypothesis(center: bool, values: list[float]) -> None:  # n
 
     result = nw.from_native(pl.from_pandas(df)).select(
         nw.col("a").rolling_var(
-            window_size, center=center, min_periods=min_periods, ddof=ddof
+            window_size, center=center, min_samples=min_samples, ddof=ddof
         )
     )
     expected_dict = nw.from_native(expected, eager_only=True).to_dict(as_series=False)
diff --git a/tests/frame/interchange_native_namespace_test.py b/tests/frame/interchange_native_namespace_test.py
index 865a675a..67fba1c1 100644
--- a/tests/frame/interchange_native_namespace_test.py
+++ b/tests/frame/interchange_native_namespace_test.py
@@ -28,9 +28,13 @@ def test_interchange() -> None:
 
 @pytest.mark.filterwarnings("ignore:.*The `ArrowDtype` class is not available in pandas")
 def test_ibis(
-    tmpdir: pytest.TempdirFactory,
+    tmpdir: pytest.TempdirFactory, request: pytest.FixtureRequest
 ) -> None:  # pragma: no cover
     ibis = pytest.importorskip("ibis")
+    try:
+        ibis.set_backend("duckdb")
+    except ImportError:
+        request.applymarker(pytest.mark.xfail)
     df_pl = pl.DataFrame(data)
 
     filepath = str(tmpdir / "file.parquet")  # type: ignore[operator]
diff --git a/tests/frame/interchange_schema_test.py b/tests/frame/interchange_schema_test.py
index a9482811..4ece51b3 100644
--- a/tests/frame/interchange_schema_test.py
+++ b/tests/frame/interchange_schema_test.py
@@ -70,9 +70,13 @@ def test_interchange_schema() -> None:
 
 @pytest.mark.filterwarnings("ignore:.*locale specific date formats")
 def test_interchange_schema_ibis(
-    tmpdir: pytest.TempdirFactory,
+    tmpdir: pytest.TempdirFactory, request: pytest.FixtureRequest
 ) -> None:  # pragma: no cover
     ibis = pytest.importorskip("ibis")
+    try:
+        ibis.set_backend("duckdb")
+    except ImportError:
+        request.applymarker(pytest.mark.xfail)
     df_pl = pl.DataFrame(
         {
             "a": [1, 1, 2],
diff --git a/tests/frame/interchange_select_test.py b/tests/frame/interchange_select_test.py
index cb28ca39..4e1400fd 100644
--- a/tests/frame/interchange_select_test.py
+++ b/tests/frame/interchange_select_test.py
@@ -47,9 +47,13 @@ def test_interchange() -> None:
 
 
 def test_interchange_ibis(
-    tmpdir: pytest.TempdirFactory,
+    tmpdir: pytest.TempdirFactory, request: pytest.FixtureRequest
 ) -> None:  # pragma: no cover
     ibis = pytest.importorskip("ibis")
+    try:
+        ibis.set_backend("duckdb")
+    except ImportError:
+        request.applymarker(pytest.mark.xfail)
     df_pl = pl.DataFrame(data)
 
     filepath = str(tmpdir / "file.parquet")  # type: ignore[operator]
diff --git a/tests/frame/interchange_to_arrow_test.py b/tests/frame/interchange_to_arrow_test.py
index 1f01b67c..064d1583 100644
--- a/tests/frame/interchange_to_arrow_test.py
+++ b/tests/frame/interchange_to_arrow_test.py
@@ -18,9 +18,13 @@ def test_interchange_to_arrow() -> None:
 
 
 def test_interchange_ibis_to_arrow(
-    tmpdir: pytest.TempdirFactory,
+    tmpdir: pytest.TempdirFactory, request: pytest.FixtureRequest
 ) -> None:  # pragma: no cover
     ibis = pytest.importorskip("ibis")
+    try:
+        ibis.set_backend("duckdb")
+    except ImportError:
+        request.applymarker(pytest.mark.xfail)
     df_pl = pl.DataFrame(data)
 
     filepath = str(tmpdir / "file.parquet")  # type: ignore[operator]
diff --git a/tests/frame/interchange_to_pandas_test.py b/tests/frame/interchange_to_pandas_test.py
index 7761a649..d9d0a878 100644
--- a/tests/frame/interchange_to_pandas_test.py
+++ b/tests/frame/interchange_to_pandas_test.py
@@ -26,6 +26,10 @@ def test_interchange_ibis_to_pandas(
         request.applymarker(pytest.mark.xfail)
 
     ibis = pytest.importorskip("ibis")
+    try:
+        ibis.set_backend("duckdb")
+    except ImportError:
+        request.applymarker(pytest.mark.xfail)
     df_raw = pd.DataFrame(data)
 
     filepath = str(tmpdir / "file.parquet")  # type: ignore[operator]