Path: blob/main/py-polars/tests/unit/functions/test_functions.py
6939 views
from __future__ import annotations12from typing import TYPE_CHECKING, Any34import numpy as np5import pytest67import polars as pl8from polars.exceptions import DuplicateError, InvalidOperationError9from polars.testing import assert_frame_equal, assert_series_equal1011if TYPE_CHECKING:12from polars._typing import ConcatMethod131415def test_concat_align() -> None:16a = pl.DataFrame({"a": ["a", "b", "d", "e", "e"], "b": [1, 2, 4, 5, 6]})17b = pl.DataFrame({"a": ["a", "b", "c"], "c": [5.5, 6.0, 7.5]})18c = pl.DataFrame({"a": ["a", "b", "c", "d", "e"], "d": ["w", "x", "y", "z", None]})1920for align_full in ("align", "align_full"):21result = pl.concat([a, b, c], how=align_full)22expected = pl.DataFrame(23{24"a": ["a", "b", "c", "d", "e", "e"],25"b": [1, 2, None, 4, 5, 6],26"c": [5.5, 6.0, 7.5, None, None, None],27"d": ["w", "x", "y", "z", None, None],28}29)30assert_frame_equal(result, expected)3132result = pl.concat([a, b, c], how="align_left")33expected = pl.DataFrame(34{35"a": ["a", "b", "d", "e", "e"],36"b": [1, 2, 4, 5, 6],37"c": [5.5, 6.0, None, None, None],38"d": ["w", "x", "z", None, None],39}40)41assert_frame_equal(result, expected)4243result = pl.concat([a, b, c], how="align_right")44expected = pl.DataFrame(45{46"a": ["a", "b", "c", "d", "e"],47"b": [1, 2, None, None, None],48"c": [5.5, 6.0, 7.5, None, None],49"d": ["w", "x", "y", "z", None],50}51)52assert_frame_equal(result, expected)5354result = pl.concat([a, b, c], how="align_inner")55expected = pl.DataFrame(56{57"a": ["a", "b"],58"b": [1, 2],59"c": [5.5, 6.0],60"d": ["w", "x"],61}62)63assert_frame_equal(result, expected)646566@pytest.mark.parametrize(67"strategy", ["align", "align_full", "align_left", "align_right"]68)69def test_concat_align_no_common_cols(strategy: ConcatMethod) -> None:70df1 = pl.DataFrame({"a": [1, 2], "b": [1, 2]})71df2 = pl.DataFrame({"c": [3, 4], "d": [3, 4]})7273with pytest.raises(74InvalidOperationError,75match=f"{strategy!r} strategy requires at least one common column",76):77pl.concat((df1, df2), how=strategy)787980@pytest.mark.parametrize(81("a", "b", "c", "strategy"),82[83(84pl.DataFrame({"a": [1, 2]}),85pl.DataFrame({"b": ["a", "b"], "c": [3, 4]}),86pl.DataFrame({"a": [5, 6], "c": [5, 6], "d": [5, 6], "b": ["x", "y"]}),87"diagonal",88),89(90pl.DataFrame(91{"a": [1, 2]},92schema_overrides={"a": pl.Int32},93),94pl.DataFrame(95{"b": ["a", "b"], "c": [3, 4]},96schema_overrides={"c": pl.UInt8},97),98pl.DataFrame(99{"a": [5, 6], "c": [5, 6], "d": [5, 6], "b": ["x", "y"]},100schema_overrides={"b": pl.Categorical},101),102"diagonal_relaxed",103),104],105)106def test_concat_diagonal(107a: pl.DataFrame, b: pl.DataFrame, c: pl.DataFrame, strategy: ConcatMethod108) -> None:109for out in [110pl.concat([a, b, c], how=strategy),111pl.concat([a.lazy(), b.lazy(), c.lazy()], how=strategy).collect(),112]:113expected = pl.DataFrame(114{115"a": [1, 2, None, None, 5, 6],116"b": [None, None, "a", "b", "x", "y"],117"c": [None, None, 3, 4, 5, 6],118"d": [None, None, None, None, 5, 6],119}120)121assert_frame_equal(out, expected)122123124def test_concat_diagonal_relaxed_with_empty_frame() -> None:125df1 = pl.DataFrame()126df2 = pl.DataFrame(127{128"a": ["a", "b"],129"b": [1, 2],130}131)132out = pl.concat((df1, df2), how="diagonal_relaxed")133expected = df2134assert_frame_equal(out, expected)135136137@pytest.mark.parametrize("lazy", [False, True])138def test_concat_horizontal(lazy: bool) -> None:139a = pl.DataFrame({"a": ["a", "b"], "b": [1, 2]})140b = pl.DataFrame({"c": [5, 7, 8, 9], "d": [1, 2, 1, 2], "e": [1, 2, 1, 2]})141142if lazy:143out = pl.concat([a.lazy(), b.lazy()], how="horizontal").collect()144else:145out = pl.concat([a, b], how="horizontal")146147expected = pl.DataFrame(148{149"a": ["a", "b", None, None],150"b": [1, 2, None, None],151"c": [5, 7, 8, 9],152"d": [1, 2, 1, 2],153"e": [1, 2, 1, 2],154}155)156assert_frame_equal(out, expected)157158159@pytest.mark.parametrize("lazy", [False, True])160def test_concat_horizontal_three_dfs(lazy: bool) -> None:161a = pl.DataFrame({"a1": [1, 2, 3], "a2": ["a", "b", "c"]})162b = pl.DataFrame({"b1": [0.25, 0.5]})163c = pl.DataFrame({"c1": [1, 2, 3, 4], "c2": [5, 6, 7, 8], "c3": [9, 10, 11, 12]})164165if lazy:166out = pl.concat([a.lazy(), b.lazy(), c.lazy()], how="horizontal").collect()167else:168out = pl.concat([a, b, c], how="horizontal")169170expected = pl.DataFrame(171{172"a1": [1, 2, 3, None],173"a2": ["a", "b", "c", None],174"b1": [0.25, 0.5, None, None],175"c1": [1, 2, 3, 4],176"c2": [5, 6, 7, 8],177"c3": [9, 10, 11, 12],178}179)180assert_frame_equal(out, expected)181182183@pytest.mark.parametrize("lazy", [False, True])184def test_concat_horizontal_single_df(lazy: bool) -> None:185a = pl.DataFrame({"a": ["a", "b"], "b": [1, 2]})186187if lazy:188out = pl.concat([a.lazy()], how="horizontal").collect()189else:190out = pl.concat([a], how="horizontal")191192expected = a193assert_frame_equal(out, expected)194195196def test_concat_horizontal_duplicate_col() -> None:197a = pl.LazyFrame({"a": ["a", "b"], "b": [1, 2]})198b = pl.LazyFrame({"c": [5, 7, 8, 9], "d": [1, 2, 1, 2], "a": [1, 2, 1, 2]})199200with pytest.raises(DuplicateError):201pl.concat([a, b], how="horizontal").collect()202203204def test_concat_vertical() -> None:205a = pl.DataFrame({"a": ["a", "b"], "b": [1, 2]})206b = pl.DataFrame({"a": ["c", "d", "e"], "b": [3, 4, 5]})207208result = pl.concat([a, b], how="vertical")209expected = pl.DataFrame(210{211"a": ["a", "b", "c", "d", "e"],212"b": [1, 2, 3, 4, 5],213}214)215assert_frame_equal(result, expected)216217218def test_cov() -> None:219s1 = pl.Series("a", [10, 37, -40])220s2 = pl.Series("b", [70, -10, 35])221222# lazy/expression223lf = pl.LazyFrame([s1, s2])224res1 = lf.select(225x=pl.cov("a", "b"),226y=pl.cov("a", "b", ddof=2),227).collect()228229# eager/series230res2 = (231pl.cov(s1, s2, eager=True).alias("x"),232pl.cov(s1, s2, eager=True, ddof=2).alias("y"),233)234235# expect same result from both approaches236for idx, (r1, r2) in enumerate(zip(res1, res2)):237expected_value = -645.8333333333 if idx == 0 else -1291.6666666666238assert pytest.approx(expected_value) == r1.item()239assert_series_equal(r1, r2)240241242def test_corr() -> None:243s1 = pl.Series("a", [10, 37, -40])244s2 = pl.Series("b", [70, -10, 35])245246# lazy/expression247lf = pl.LazyFrame([s1, s2])248res1 = lf.select(249x=pl.corr("a", "b"),250y=pl.corr("a", "b", method="spearman"),251).collect()252253# eager/series254res2 = (255pl.corr(s1, s2, eager=True).alias("x"),256pl.corr(s1, s2, method="spearman", eager=True).alias("y"),257)258259# expect same result from both approaches260for idx, (r1, r2) in enumerate(zip(res1, res2)):261assert pytest.approx(-0.412199756 if idx == 0 else -0.5) == r1.item()262assert_series_equal(r1, r2)263264265def test_extend_ints() -> None:266a = pl.DataFrame({"a": [1 for _ in range(1)]}, schema={"a": pl.Int64})267with pytest.raises(pl.exceptions.SchemaError):268a.extend(a.select(pl.lit(0, dtype=pl.Int32).alias("a")))269270271def test_null_handling_correlation() -> None:272df = pl.DataFrame({"a": [1, 2, 3, None, 4], "b": [1, 2, 3, 10, 4]})273274out = df.select(275pl.corr("a", "b").alias("pearson"),276pl.corr("a", "b", method="spearman").alias("spearman"),277)278assert out["pearson"][0] == pytest.approx(1.0)279assert out["spearman"][0] == pytest.approx(1.0)280281# see #4930282df1 = pl.DataFrame({"a": [None, 1, 2], "b": [None, 2, 1]})283df2 = pl.DataFrame({"a": [np.nan, 1, 2], "b": [np.nan, 2, 1]})284285assert np.isclose(df1.select(pl.corr("a", "b", method="spearman")).item(), -1.0)286assert (287str(288df2.select(pl.corr("a", "b", method="spearman", propagate_nans=True)).item()289)290== "nan"291)292293294def test_align_frames() -> None:295import numpy as np296import pandas as pd297298# setup some test frames299pdf1 = pd.DataFrame(300{301"date": pd.date_range(start="2019-01-02", periods=9),302"a": np.array([0, 1, 2, np.nan, 4, 5, 6, 7, 8], dtype=np.float64),303"b": np.arange(9, 18, dtype=np.float64),304}305).set_index("date")306307pdf2 = pd.DataFrame(308{309"date": pd.date_range(start="2019-01-04", periods=7),310"a": np.arange(9, 16, dtype=np.float64),311"b": np.arange(10, 17, dtype=np.float64),312}313).set_index("date")314315# calculate dot-product in pandas316pd_dot = (pdf1 * pdf2).sum(axis="columns").to_frame("dot").reset_index()317318# use "align_frames" to calculate dot-product from disjoint rows. pandas uses an319# index to automatically infer the correct frame-alignment for the calculation;320# we need to do it explicitly (which also makes it clearer what is happening)321pf1, pf2 = pl.align_frames(322pl.from_pandas(pdf1.reset_index()),323pl.from_pandas(pdf2.reset_index()),324on="date",325)326pl_dot = (327(pf1[["a", "b"]] * pf2[["a", "b"]])328.fill_null(0)329.select(pl.sum_horizontal("*").alias("dot"))330.insert_column(0, pf1["date"])331)332# confirm we match the same operation in pandas333assert_frame_equal(pl_dot, pl.from_pandas(pd_dot))334pd.testing.assert_frame_equal(pd_dot, pl_dot.to_pandas())335336# confirm alignment function works with lazy frames337lf1, lf2 = pl.align_frames(338pl.from_pandas(pdf1.reset_index()).lazy(),339pl.from_pandas(pdf2.reset_index()).lazy(),340on="date",341)342assert isinstance(lf1, pl.LazyFrame)343assert_frame_equal(lf1.collect(), pf1)344assert_frame_equal(lf2.collect(), pf2)345346# misc: no frames results in an empty list347assert pl.align_frames(on="date") == []348349# expected error condition350with pytest.raises(TypeError):351pl.align_frames( # type: ignore[type-var]352pl.from_pandas(pdf1.reset_index()).lazy(),353pl.from_pandas(pdf2.reset_index()),354on="date",355)356357358def test_align_frames_misc() -> None:359df1 = pl.DataFrame([[3, 5, 6], [5, 8, 9]], orient="row")360df2 = pl.DataFrame([[2, 5, 6], [3, 8, 9], [4, 2, 0]], orient="row")361362# descending result363pf1, pf2 = pl.align_frames(364[df1, df2], # list input365on="column_0",366descending=True,367)368assert pf1.rows() == [(5, 8, 9), (4, None, None), (3, 5, 6), (2, None, None)]369assert pf2.rows() == [(5, None, None), (4, 2, 0), (3, 8, 9), (2, 5, 6)]370371# handle identical frames372pf1, pf2, pf3 = pl.align_frames(373(df for df in (df1, df2, df2)), # generator input374on="column_0",375descending=True,376)377assert pf1.rows() == [(5, 8, 9), (4, None, None), (3, 5, 6), (2, None, None)]378for pf in (pf2, pf3):379assert pf.rows() == [(5, None, None), (4, 2, 0), (3, 8, 9), (2, 5, 6)]380381382def test_align_frames_with_nulls() -> None:383df1 = pl.DataFrame({"key": ["x", "y", None], "value": [1, 2, 0]})384df2 = pl.DataFrame({"key": ["x", None, "z", "y"], "value": [4, 3, 6, 5]})385386a1, a2 = pl.align_frames(df1, df2, on="key")387388aligned_frame_data = a1.to_dict(as_series=False), a2.to_dict(as_series=False)389assert aligned_frame_data == (390{"key": [None, "x", "y", "z"], "value": [0, 1, 2, None]},391{"key": [None, "x", "y", "z"], "value": [3, 4, 5, 6]},392)393394395def test_align_frames_duplicate_key() -> None:396# setup some test frames with duplicate key/alignment values397df1 = pl.DataFrame({"x": ["a", "a", "a", "e"], "y": [1, 2, 4, 5]})398df2 = pl.DataFrame({"y": [0, 0, -1], "z": [5.5, 6.0, 7.5], "x": ["a", "b", "b"]})399400# align rows, confirming correctness and original column order401af1, af2 = pl.align_frames(df1, df2, on="x")402403# shape: (6, 2) shape: (6, 3)404# ┌─────┬──────┐ ┌──────┬──────┬─────┐405# │ x ┆ y │ │ y ┆ z ┆ x │406# │ --- ┆ --- │ │ --- ┆ --- ┆ --- │407# │ str ┆ i64 │ │ i64 ┆ f64 ┆ str │408# ╞═════╪══════╡ ╞══════╪══════╪═════╡409# │ a ┆ 1 │ │ 0 ┆ 5.5 ┆ a │410# │ a ┆ 2 │ │ 0 ┆ 5.5 ┆ a │411# │ a ┆ 4 │ │ 0 ┆ 5.5 ┆ a │412# │ b ┆ null │ │ 0 ┆ 6.0 ┆ b │413# │ b ┆ null │ │ -1 ┆ 7.5 ┆ b │414# │ e ┆ 5 │ │ null ┆ null ┆ e │415# └─────┴──────┘ └──────┴──────┴─────┘416assert af1.rows() == [417("a", 1),418("a", 2),419("a", 4),420("b", None),421("b", None),422("e", 5),423]424assert af2.rows() == [425(0, 5.5, "a"),426(0, 5.5, "a"),427(0, 5.5, "a"),428(0, 6.0, "b"),429(-1, 7.5, "b"),430(None, None, "e"),431]432433# align frames the other way round, using "left" alignment strategy434af1, af2 = pl.align_frames(df2, df1, on="x", how="left")435436# shape: (5, 3) shape: (5, 2)437# ┌─────┬─────┬─────┐ ┌─────┬──────┐438# │ y ┆ z ┆ x │ │ x ┆ y │439# │ --- ┆ --- ┆ --- │ │ --- ┆ --- │440# │ i64 ┆ f64 ┆ str │ │ str ┆ i64 │441# ╞═════╪═════╪═════╡ ╞═════╪══════╡442# │ 0 ┆ 5.5 ┆ a │ │ a ┆ 1 │443# │ 0 ┆ 5.5 ┆ a │ │ a ┆ 2 │444# │ 0 ┆ 5.5 ┆ a │ │ a ┆ 4 │445# │ 0 ┆ 6.0 ┆ b │ │ b ┆ null │446# │ -1 ┆ 7.5 ┆ b │ │ b ┆ null │447# └─────┴─────┴─────┘ └─────┴──────┘448assert af1.rows() == [449(0, 5.5, "a"),450(0, 5.5, "a"),451(0, 5.5, "a"),452(0, 6.0, "b"),453(-1, 7.5, "b"),454]455assert af2.rows() == [456("a", 1),457("a", 2),458("a", 4),459("b", None),460("b", None),461]462463464def test_align_frames_single_row_20445() -> None:465left = pl.DataFrame({"a": [1], "b": [2]})466right = pl.DataFrame({"a": [1], "c": [3]})467result = pl.align_frames(left, right, how="left", on="a")468assert_frame_equal(result[0], left)469assert_frame_equal(result[1], right)470471472def test_coalesce() -> None:473df = pl.DataFrame(474{475"a": [1, None, None, None],476"b": [1, 2, None, None],477"c": [5, None, 3, None],478}479)480# list inputs481expected = pl.Series("d", [1, 2, 3, 10]).to_frame()482result = df.select(pl.coalesce(["a", "b", "c", 10]).alias("d"))483assert_frame_equal(expected, result)484485# positional inputs486expected = pl.Series("d", [1.0, 2.0, 3.0, 10.0]).to_frame()487result = df.select(pl.coalesce(pl.col(["a", "b", "c"]), 10.0).alias("d"))488assert_frame_equal(result, expected)489490491def test_coalesce_eager() -> None:492# eager/series inputs493s1 = pl.Series("colx", [None, 2, None])494s2 = pl.Series("coly", [1, None, None])495s3 = pl.Series("colz", [None, None, 3])496497res = pl.coalesce(s1, s2, s3, eager=True)498expected = pl.Series("colx", [1, 2, 3])499assert_series_equal(expected, res)500501for zero in (0, pl.lit(0)):502res = pl.coalesce(s1, zero, eager=True)503expected = pl.Series("colx", [0, 2, 0])504assert_series_equal(expected, res)505506res = pl.coalesce(zero, s1, eager=True)507expected = pl.Series("literal", [0, 0, 0])508assert_series_equal(expected, res)509510with pytest.raises(511ValueError,512match="expected at least one Series in 'coalesce' if 'eager=True'",513):514pl.coalesce("x", "y", eager=True)515516517def test_overflow_diff() -> None:518df = pl.DataFrame({"a": [20, 10, 30]})519assert df.select(pl.col("a").cast(pl.UInt64).diff()).to_dict(as_series=False) == {520"a": [None, -10, 20]521}522523524@pytest.mark.may_fail_cloud # reason: unknown type525def test_fill_null_unknown_output_type() -> None:526df = pl.DataFrame({"a": [None, 2, 3, 4, 5]})527assert df.with_columns(528np.exp(pl.col("a")).fill_null(pl.lit(1, pl.Float64))529).to_dict(as_series=False) == {530"a": [5311.0,5327.38905609893065,53320.085536923187668,53454.598150033144236,535148.4131591025766,536]537}538539540def test_approx_n_unique() -> None:541df1 = pl.DataFrame({"a": [None, 1, 2], "b": [None, 2, 1]})542543assert_frame_equal(544df1.select(pl.approx_n_unique("b")),545pl.DataFrame({"b": pl.Series(values=[3], dtype=pl.UInt32)}),546)547548assert_frame_equal(549df1.select(pl.col("b").approx_n_unique()),550pl.DataFrame({"b": pl.Series(values=[3], dtype=pl.UInt32)}),551)552553554def test_lazy_functions() -> None:555df = pl.DataFrame(556{557"a": ["foo", "bar", "foo"],558"b": [1, 2, 3],559"c": [-1.0, 2.0, 4.0],560}561)562563# test function expressions against frame564out = df.select(565pl.var("b").name.suffix("_var"),566pl.std("b").name.suffix("_std"),567pl.max("a", "b").name.suffix("_max"),568pl.min("a", "b").name.suffix("_min"),569pl.sum("b", "c").name.suffix("_sum"),570pl.mean("b", "c").name.suffix("_mean"),571pl.median("c", "b").name.suffix("_median"),572pl.n_unique("b", "a").name.suffix("_n_unique"),573pl.first("a").name.suffix("_first"),574pl.first("b", "c").name.suffix("_first"),575pl.last("c", "b", "a").name.suffix("_last"),576)577expected: dict[str, list[Any]] = {578"b_var": [1.0],579"b_std": [1.0],580"a_max": ["foo"],581"b_max": [3],582"a_min": ["bar"],583"b_min": [1],584"b_sum": [6],585"c_sum": [5.0],586"b_mean": [2.0],587"c_mean": [5 / 3],588"c_median": [2.0],589"b_median": [2.0],590"b_n_unique": [3],591"a_n_unique": [2],592"a_first": ["foo"],593"b_first": [1],594"c_first": [-1.0],595"c_last": [4.0],596"b_last": [3],597"a_last": ["foo"],598}599assert_frame_equal(600out,601pl.DataFrame(602data=expected,603schema_overrides={604"a_n_unique": pl.UInt32,605"b_n_unique": pl.UInt32,606},607),608)609610# test function expressions against series611for name, value in expected.items():612col, fn = name.split("_", 1)613if series_fn := getattr(df[col], fn, None):614assert series_fn() == value[0]615616# regex selection617out = df.select(618pl.struct(pl.max("^a|b$")).alias("x"),619pl.struct(pl.min("^.*[bc]$")).alias("y"),620pl.struct(pl.sum("^[^a]$")).alias("z"),621)622assert out.rows() == [623({"a": "foo", "b": 3}, {"b": 1, "c": -1.0}, {"b": 6, "c": 5.0})624]625626627def test_count() -> None:628df = pl.DataFrame({"a": [1, 1, 1], "b": [None, "xx", "yy"]})629out = df.select(pl.count("a"))630assert list(out["a"]) == [3]631632for count_expr in (633pl.count("b", "a"),634[pl.count("b"), pl.count("a")],635):636out = df.select(count_expr)637assert out.rows() == [(2, 3)]638639640def test_head_tail(fruits_cars: pl.DataFrame) -> None:641res_expr = fruits_cars.select(pl.head("A", 2))642expected = pl.Series("A", [1, 2])643assert_series_equal(res_expr.to_series(), expected)644645res_expr = fruits_cars.select(pl.tail("A", 2))646expected = pl.Series("A", [4, 5])647assert_series_equal(res_expr.to_series(), expected)648649650def test_escape_regex() -> None:651result = pl.escape_regex("abc(\\w+)")652expected = "abc\\(\\\\w\\+\\)"653assert result == expected654655df = pl.DataFrame({"text": ["abc", "def", None, "abc(\\w+)"]})656with pytest.raises(657TypeError,658match="escape_regex function is unsupported for `Expr`, you may want use `Expr.str.escape_regex` instead",659):660df.with_columns(escaped=pl.escape_regex(pl.col("text"))) # type: ignore[arg-type]661662with pytest.raises(663TypeError,664match="escape_regex function supports only `str` type, got `int`",665):666pl.escape_regex(3) # type: ignore[arg-type]667668669@pytest.mark.parametrize("func", ["var", "std"])670def test_var_std_lit_23156(func: str) -> None:671for n in range(100):672input = pl.DataFrame({"x": list(range(n))}).select(pl.col("x"), pl.lit(0))673out = getattr(input, func)()674if n <= 1:675assert_series_equal(676out["literal"], pl.Series("literal", [None], dtype=pl.Float64)677)678else:679assert_series_equal(680out["literal"], pl.Series("literal", [0.0], dtype=pl.Float64)681)682683684def test_row_index_expr() -> None:685lf = pl.LazyFrame({"x": ["A", "A", "B", "B", "B"]})686687assert_frame_equal(688lf.with_columns(pl.row_index(), pl.row_index("another_index")).collect(),689pl.DataFrame(690{691"x": ["A", "A", "B", "B", "B"],692"index": [0, 1, 2, 3, 4],693"another_index": [0, 1, 2, 3, 4],694},695schema={696"x": pl.String,697"index": pl.get_index_type(),698"another_index": pl.get_index_type(),699},700),701)702703assert_frame_equal(704(705lf.group_by("x")706.agg(pl.row_index(), pl.row_index("another_index"))707.sort("x")708.collect()709),710pl.DataFrame(711{712"x": ["A", "B"],713"index": [[0, 1], [0, 1, 2]],714"another_index": [[0, 1], [0, 1, 2]],715},716schema={717"x": pl.String,718"index": pl.List(pl.get_index_type()),719"another_index": pl.List(pl.get_index_type()),720},721),722)723724assert_frame_equal(725lf.select(pl.row_index()).collect(),726pl.DataFrame(727{"index": [0, 1, 2, 3, 4]},728schema={"index": pl.get_index_type()},729),730)731732733