Path: blob/main/py-polars/tests/unit/series/test_rolling.py
8424 views
from datetime import datetime1from typing import Any23import pytest45import polars as pl6from polars.testing.asserts.series import assert_series_equal789@pytest.fixture10def values() -> pl.Series:11return pl.Series([6, 9, 2, 5, 8, 1, 4, 7])121314@pytest.fixture15def by_col() -> pl.Series:16return pl.Series([0, 0, 1, 1, 2, 2, 3, 3])171819@pytest.fixture20def by_col_temporal() -> pl.Series:21return pl.Series(22pl.datetime_range(23datetime(2025, 1, 1), datetime(2025, 1, 2), "1h", eager=True24).head(8)25)262728def test_series_rolling_min_by(values: pl.Series, by_col: pl.Series) -> None:29actual = values.rolling_min_by(by_col, "2i")30expected = pl.Series([6, 6, 2, 2, 1, 1, 1, 1])31assert_series_equal(actual, expected)323334def test_series_rolling_max_by(values: pl.Series, by_col: pl.Series) -> None:35actual = values.rolling_max_by(by_col, "2i")36expected = pl.Series([9, 9, 9, 9, 8, 8, 8, 8])37assert_series_equal(actual, expected)383940def test_series_rolling_sum_by(values: pl.Series, by_col: pl.Series) -> None:41actual = values.rolling_sum_by(by_col, "2i")42expected = pl.Series([15, 15, 22, 22, 16, 16, 20, 20])43assert_series_equal(actual, expected)444546def test_series_rolling_mean_by(values: pl.Series, by_col: pl.Series) -> None:47actual = values.rolling_mean_by(by_col, "2i")48expected = pl.Series([7.5, 7.5, 5.5, 5.5, 4.0, 4.0, 5.0, 5.0])49assert_series_equal(actual, expected)505152@pytest.mark.parametrize(53("op", "expected"),54[55("mean", [None, None, 5.0, 5.0, 4.67, 4.67, 5.0, 5.0]),56("sum", [0, 0, 5, 5, 14, 14, 20, 20]),57("min", [None, None, 5, 5, 1, 1, 1, 1]),58("max", [None, None, 5, 5, 8, 8, 8, 8]),59("var", [None, None, None, None, 12.33, 12.33, 10.0, 10.0]),60("std", [None, None, None, None, 3.51, 3.51, 3.16, 3.16]),61],62)63def test_series_rolling_by_with_nulls(64values: pl.Series, by_col: pl.Series, op: str, expected: list[float]65) -> None:66values[[0, 1, 2]] = None67actual = getattr(values, f"rolling_{op}_by")(by_col, "2i").round(2)68assert_series_equal(actual, pl.Series(expected))697071@pytest.mark.parametrize(72("rank_op", "expected"),73[74("average", [None, None, None, 1.0, 3.0, 1.0, 2.0, 3.0]),75("min", [None, None, None, 1, 3, 1, 2, 3]),76("max", [None, None, None, 1, 3, 1, 2, 3]),77("dense", [None, None, None, 1, 3, 1, 2, 3]),78("random", [None, None, None, 1, 3, 1, 2, 3]),79],80)81def test_series_rolling_rank_by_with_nulls(82values: pl.Series, by_col: pl.Series, rank_op: Any, expected: list[float]83) -> None:84values[[0, 1, 2]] = None85actual = values.rolling_rank_by(by_col, "2i", rank_op).round(2)86dtype = pl.Float64 if rank_op == "average" else pl.UInt3287assert_series_equal(actual, pl.Series(expected, dtype=dtype))888990def test_series_rolling_quantile_by_with_nulls(91values: pl.Series, by_col: pl.Series92) -> None:93values[[0, 1, 2]] = None94actual = values.rolling_quantile_by(by_col, "2i", quantile=0.35).round(2)95expected = [None, None, 5.0, 5.0, 5.0, 5.0, 4.0, 4.0]96assert_series_equal(actual, pl.Series(expected))979899def test_series_rolling_median_by(values: pl.Series, by_col: pl.Series) -> None:100actual = values.rolling_median_by(by_col, "2i")101expected = pl.Series([7.5, 7.5, 5.5, 5.5, 3.5, 3.5, 5.5, 5.5])102assert_series_equal(actual, expected)103104105def test_series_rolling_std_by(values: pl.Series, by_col: pl.Series) -> None:106actual = values.rolling_std_by(by_col, "2i")107expected = pl.Series([2.12, 2.12, 2.88, 2.88, 3.16, 3.16, 3.16, 3.16])108assert_series_equal(actual, expected, abs_tol=1e-2)109110111def test_series_rolling_var_by(values: pl.Series, by_col: pl.Series) -> None:112actual = values.rolling_var_by(by_col, "2i")113expected = pl.Series([4.5, 4.5, 8.33, 8.33, 10.0, 10.0, 10.0, 10.0])114assert_series_equal(actual, expected, abs_tol=1e-2)115116117def test_series_rolling_quantile_by(values: pl.Series, by_col: pl.Series) -> None:118actual = values.rolling_quantile_by(by_col, "2i", quantile=0.5)119expected = pl.Series([9.0, 9.0, 6.0, 6.0, 5.0, 5.0, 7.0, 7.0])120assert_series_equal(actual, expected)121122123def test_series_rolling_rank_by(values: pl.Series, by_col: pl.Series) -> None:124actual = values.rolling_rank_by(by_col, "2i", method="average")125expected = pl.Series([1.0, 2.0, 1.0, 2.0, 4.0, 1.0, 2.0, 3.0])126assert_series_equal(actual, expected)127128129def test_series_rolling_min_by_temporal(130values: pl.Series, by_col_temporal: pl.Series131) -> None:132actual = values.rolling_min_by(by_col_temporal, "2h")133expected = pl.Series([6, 6, 2, 2, 5, 1, 1, 4])134assert_series_equal(actual, expected)135136137def test_series_rolling_max_by_temporal(138values: pl.Series, by_col_temporal: pl.Series139) -> None:140actual = values.rolling_max_by(by_col_temporal, "2h")141expected = pl.Series([6, 9, 9, 5, 8, 8, 4, 7])142assert_series_equal(actual, expected)143144145def test_series_rolling_sum_by_temporal(146values: pl.Series, by_col_temporal: pl.Series147) -> None:148actual = values.rolling_sum_by(by_col_temporal, "2h")149expected = pl.Series([6, 15, 11, 7, 13, 9, 5, 11])150assert_series_equal(actual, expected)151152153def test_series_rolling_mean_by_temporal(154values: pl.Series, by_col_temporal: pl.Series155) -> None:156actual = values.rolling_mean_by(by_col_temporal, "2h")157expected = pl.Series([6.0, 7.5, 5.5, 3.5, 6.5, 4.5, 2.5, 5.5])158assert_series_equal(actual, expected)159160161def test_series_rolling_median_by_temporal(162values: pl.Series, by_col_temporal: pl.Series163) -> None:164actual = values.rolling_median_by(by_col_temporal, "3h")165expected = pl.Series([6.0, 7.5, 6.0, 5.0, 5.0, 5.0, 4.0, 4.0])166assert_series_equal(actual, expected)167168169def test_series_rolling_std_by_temporal(170values: pl.Series, by_col_temporal: pl.Series171) -> None:172actual = values.rolling_std_by(by_col_temporal, "2h")173expected = pl.Series([None, 2.12, 4.94, 2.12, 2.12, 4.94, 2.12, 2.12])174assert_series_equal(actual, expected, abs_tol=1e-2)175176177def test_series_rolling_var_by_temporal(178values: pl.Series, by_col_temporal: pl.Series179) -> None:180actual = values.rolling_var_by(by_col_temporal, "2h")181expected = pl.Series([None, 4.5, 24.5, 4.5, 4.5, 24.5, 4.5, 4.5])182assert_series_equal(actual, expected, abs_tol=1e-2)183184185def test_series_rolling_quantile_by_temporal(186values: pl.Series, by_col_temporal: pl.Series187) -> None:188actual = values.rolling_quantile_by(by_col_temporal, "2h", quantile=0.5)189expected = pl.Series([6.0, 9.0, 9.0, 5.0, 8.0, 8.0, 4.0, 7.0])190assert_series_equal(actual, expected)191192193def test_series_rolling_rank_by_temporal(194values: pl.Series, by_col_temporal: pl.Series195) -> None:196actual = values.rolling_rank_by(by_col_temporal, "2h", method="average")197expected = pl.Series([1.0, 2.0, 1.0, 2.0, 2.0, 1.0, 2.0, 2.0])198assert_series_equal(actual, expected)199200201