diff --git a/narwhals/expr.py b/narwhals/expr.py index aa934a01f..3e457989a 100644 --- a/narwhals/expr.py +++ b/narwhals/expr.py @@ -63,23 +63,27 @@ def alias(self, name: str) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [4, 5]}) - >>> df_pl = pl.DataFrame({"a": [1, 2], "b": [4, 5]}) - >>> df_pa = pa.table({"a": [1, 2], "b": [4, 5]}) + >>> + >>> data = {"a": [1, 2], "b": [4, 5]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_alias(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select((nw.col("b") + 10).alias("c")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_alias`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_alias(df_pd) c 0 14 1 15 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_alias(df_pl) shape: (2, 1) ┌─────┐ │ c │ @@ -89,7 +93,8 @@ def alias(self, name: str) -> Self: │ 14 │ │ 15 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_alias(df_pa) pyarrow.Table c: int64 ---- @@ -110,11 +115,12 @@ def pipe(self, function: Callable[[Any], Self], *args: Any, **kwargs: Any) -> Se A new expression. Examples: - >>> import polars as pl >>> import pandas as pd + >>> import polars as pl >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3, 4]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -122,19 +128,21 @@ def pipe(self, function: Callable[[Any], Self], *args: Any, **kwargs: Any) -> Se Lets define a library-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_pipe(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").pipe(lambda x: x + 1)).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_pipe`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_pipe(df_pd) a 0 2 1 3 2 4 3 5 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_pipe(df_pl) shape: (4, 1) ┌─────┐ │ a │ @@ -146,7 +154,8 @@ def pipe(self, function: Callable[[Any], Self], *args: Any, **kwargs: Any) -> Se │ 4 │ │ 5 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_pipe(df_pa) pyarrow.Table a: int64 ---- @@ -169,27 +178,29 @@ def cast(self: Self, dtype: DType | type[DType]) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> from datetime import date - >>> df_pd = pd.DataFrame({"foo": [1, 2, 3], "bar": [6.0, 7.0, 8.0]}) - >>> df_pl = pl.DataFrame({"foo": [1, 2, 3], "bar": [6.0, 7.0, 8.0]}) - >>> df_pa = pa.table({"foo": [1, 2, 3], "bar": [6.0, 7.0, 8.0]}) + >>> + >>> data = {"foo": [1, 2, 3], "bar": [6.0, 7.0, 8.0]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_cast(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("foo").cast(nw.Float32), nw.col("bar").cast(nw.UInt8) ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_cast`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_cast(df_pd) foo bar 0 1.0 6 1 2.0 7 2 3.0 8 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_cast(df_pl) shape: (3, 2) ┌─────┬─────┐ │ foo ┆ bar │ @@ -200,7 +211,7 @@ def cast(self: Self, dtype: DType | type[DType]) -> Self: │ 2.0 ┆ 7 │ │ 3.0 ┆ 8 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_cast(df_pa) pyarrow.Table foo: float bar: uint8 @@ -393,22 +404,26 @@ def any(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [True, False], "b": [True, True]}) - >>> df_pl = pl.DataFrame({"a": [True, False], "b": [True, True]}) - >>> df_pa = pa.table({"a": [True, False], "b": [True, True]}) + >>> + >>> data = {"a": [True, False], "b": [True, True]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_any(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").any()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_any`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_any(df_pd) a b 0 True True - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_any(df_pl) shape: (1, 2) ┌──────┬──────┐ │ a ┆ b │ @@ -417,7 +432,8 @@ def any(self) -> Self: ╞══════╪══════╡ │ true ┆ true │ └──────┴──────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_any(df_pa) pyarrow.Table a: bool b: bool @@ -439,22 +455,26 @@ def all(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [True, False], "b": [True, True]}) - >>> df_pl = pl.DataFrame({"a": [True, False], "b": [True, True]}) - >>> df_pa = pa.table({"a": [True, False], "b": [True, True]}) + >>> + >>> data = {"a": [True, False], "b": [True, True]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_all(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").all()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_all`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_all(df_pd) a b 0 False True - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_all(df_pl) shape: (1, 2) ┌───────┬──────┐ │ a ┆ b │ @@ -463,7 +483,8 @@ def all(self) -> Self: ╞═══════╪══════╡ │ false ┆ true │ └───────┴──────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_all(df_pa) pyarrow.Table a: bool b: bool @@ -530,27 +551,28 @@ def ewm_mean( >>> import polars as pl >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) We define a library agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_ewm_mean(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("a").ewm_mean(com=1, ignore_nulls=False) ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass either pandas or Polars to `agnostic_ewm_mean`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_ewm_mean(df_pd) a 0 1.000000 1 1.666667 2 2.428571 - >>> my_library_agnostic_function(df_pl) # doctest: +NORMALIZE_WHITESPACE + >>> agnostic_ewm_mean(df_pl) # doctest: +NORMALIZE_WHITESPACE shape: (3, 1) ┌──────────┐ │ a │ @@ -586,22 +608,26 @@ def mean(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [-1, 0, 1], "b": [2, 4, 6]}) - >>> df_pl = pl.DataFrame({"a": [-1, 0, 1], "b": [2, 4, 6]}) - >>> df_pa = pa.table({"a": [-1, 0, 1], "b": [2, 4, 6]}) + >>> + >>> data = {"a": [-1, 0, 1], "b": [2, 4, 6]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_mean(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").mean()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_mean`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_mean(df_pd) a b 0 0.0 4.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_mean(df_pl) shape: (1, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -610,7 +636,8 @@ def mean(self) -> Self: ╞═════╪═════╡ │ 0.0 ┆ 4.0 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_mean(df_pa) pyarrow.Table a: double b: double @@ -635,22 +662,26 @@ def median(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 8, 3], "b": [4, 5, 2]}) - >>> df_pl = pl.DataFrame({"a": [1, 8, 3], "b": [4, 5, 2]}) - >>> df_pa = pa.table({"a": [1, 8, 3], "b": [4, 5, 2]}) + >>> + >>> data = {"a": [1, 8, 3], "b": [4, 5, 2]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_median(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").median()).to_native() - We can then pass any supported library such as pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_median`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_median(df_pd) a b 0 3.0 4.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_median(df_pl) shape: (1, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -659,7 +690,8 @@ def median(self) -> Self: ╞═════╪═════╡ │ 3.0 ┆ 4.0 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_median(df_pa) pyarrow.Table a: double b: double @@ -674,7 +706,7 @@ def std(self, *, ddof: int = 1) -> Self: Arguments: ddof: "Delta Degrees of Freedom": the divisor used in the calculation is N - ddof, - where N represents the number of elements. By default ddof is 1. + where N represents the number of elements. By default ddof is 1. Returns: A new expression. @@ -685,22 +717,25 @@ def std(self, *, ddof: int = 1) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [20, 25, 60], "b": [1.5, 1, -1.4]}) - >>> df_pl = pl.DataFrame({"a": [20, 25, 60], "b": [1.5, 1, -1.4]}) - >>> df_pa = pa.table({"a": [20, 25, 60], "b": [1.5, 1, -1.4]}) + >>> + >>> data = {"a": [20, 25, 60], "b": [1.5, 1, -1.4]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_std(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").std(ddof=0)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_std`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_std(df_pd) a b 0 17.79513 1.265789 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_std(df_pl) shape: (1, 2) ┌──────────┬──────────┐ │ a ┆ b │ @@ -709,7 +744,7 @@ def std(self, *, ddof: int = 1) -> Self: ╞══════════╪══════════╡ │ 17.79513 ┆ 1.265789 │ └──────────┴──────────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_std(df_pa) pyarrow.Table a: double b: double @@ -736,9 +771,11 @@ def var(self, *, ddof: int = 1) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [20, 25, 60], "b": [1.5, 1, -1.4]}) - >>> df_pl = pl.DataFrame({"a": [20, 25, 60], "b": [1.5, 1, -1.4]}) - >>> df_pa = pa.table({"a": [20, 25, 60], "b": [1.5, 1, -1.4]}) + >>> + >>> data = {"a": [20, 25, 60], "b": [1.5, 1, -1.4]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: @@ -746,11 +783,13 @@ def var(self, *, ddof: int = 1) -> Self: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").var(ddof=0)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_var`: >>> agnostic_var(df_pd) a b 0 316.666667 1.602222 + >>> agnostic_var(df_pl) shape: (1, 2) ┌────────────┬──────────┐ @@ -760,6 +799,7 @@ def var(self, *, ddof: int = 1) -> Self: ╞════════════╪══════════╡ │ 316.666667 ┆ 1.602222 │ └────────────┴──────────┘ + >>> agnostic_var(df_pa) pyarrow.Table a: double @@ -796,6 +836,7 @@ def map_batches( >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3], "b": [4, 5, 6]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -803,7 +844,7 @@ def map_batches( Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_map_batches(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("a", "b").map_batches( @@ -811,14 +852,15 @@ def map_batches( ... ) ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_map_batches`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_map_batches(df_pd) a b 0 2.0 5.0 1 3.0 6.0 2 4.0 7.0 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_map_batches(df_pl) shape: (3, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -829,7 +871,7 @@ def map_batches( │ 3.0 ┆ 6.0 │ │ 4.0 ┆ 7.0 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_map_batches(df_pa) pyarrow.Table a: double b: double @@ -854,22 +896,27 @@ def skew(self: Self) -> Self: >>> import polars as pl >>> import pyarrow as pa >>> import narwhals as nw - >>> df_pd = pd.DataFrame({"a": [1, 2, 3, 4, 5], "b": [1, 1, 2, 10, 100]}) - >>> df_pl = pl.DataFrame({"a": [1, 2, 3, 4, 5], "b": [1, 1, 2, 10, 100]}) - >>> df_pa = pa.Table.from_pandas(df_pd) + >>> from narwhals.typing import IntoFrameT + >>> + >>> data = {"a": [1, 2, 3, 4, 5], "b": [1, 1, 2, 10, 100]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> @nw.narwhalify - ... def func(df): - ... return df.select(nw.col("a", "b").skew()) + >>> def agnostic_skew(df_native: IntoFrameT) -> IntoFrameT: + ... df = nw.from_native(df_native) + ... return df.select(nw.col("a", "b").skew()).to_native() - We can then pass pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_skew`: - >>> func(df_pd) + >>> agnostic_skew(df_pd) a b 0 0.0 1.472427 - >>> func(df_pl) + + >>> agnostic_skew(df_pl) shape: (1, 2) ┌─────┬──────────┐ │ a ┆ b │ @@ -878,7 +925,8 @@ def skew(self: Self) -> Self: ╞═════╪══════════╡ │ 0.0 ┆ 1.472427 │ └─────┴──────────┘ - >>> func(df_pa) + + >>> agnostic_skew(df_pa) pyarrow.Table a: double b: double @@ -900,22 +948,25 @@ def sum(self) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [5, 10], "b": [50, 100]}) - >>> df_pl = pl.DataFrame({"a": [5, 10], "b": [50, 100]}) - >>> df_pa = pa.table({"a": [5, 10], "b": [50, 100]}) + >>> + >>> data = {"a": [5, 10], "b": [50, 100]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_sum(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").sum()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_sum`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_sum(df_pd) a b 0 15 150 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_sum(df_pl) shape: (1, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -924,7 +975,7 @@ def sum(self) -> Expr: ╞═════╪═════╡ │ 15 ┆ 150 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_sum(df_pa) pyarrow.Table a: int64 b: int64 @@ -946,22 +997,26 @@ def min(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [4, 3]}) - >>> df_pl = pl.DataFrame({"a": [1, 2], "b": [4, 3]}) - >>> df_pa = pa.table({"a": [1, 2], "b": [4, 3]}) + >>> + >>> data = {"a": [1, 2], "b": [4, 3]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_min(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.min("a", "b")).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_min`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_min(df_pd) a b 0 1 3 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_min(df_pl) shape: (1, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -970,7 +1025,8 @@ def min(self) -> Self: ╞═════╪═════╡ │ 1 ┆ 3 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_min(df_pa) pyarrow.Table a: int64 b: int64 @@ -992,22 +1048,26 @@ def max(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [10, 20], "b": [50, 100]}) - >>> df_pl = pl.DataFrame({"a": [10, 20], "b": [50, 100]}) - >>> df_pa = pa.table({"a": [10, 20], "b": [50, 100]}) + >>> + >>> data = {"a": [10, 20], "b": [50, 100]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_max(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.max("a", "b")).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_max`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_max(df_pd) a b 0 20 100 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_max(df_pl) shape: (1, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -1016,7 +1076,8 @@ def max(self) -> Self: ╞═════╪═════╡ │ 20 ┆ 100 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_max(df_pa) pyarrow.Table a: int64 b: int64 @@ -1038,9 +1099,11 @@ def arg_min(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [10, 20], "b": [150, 100]}) - >>> df_pl = pl.DataFrame({"a": [10, 20], "b": [150, 100]}) - >>> df_pa = pa.table({"a": [10, 20], "b": [150, 100]}) + >>> + >>> data = {"a": [10, 20], "b": [150, 100]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: @@ -1050,11 +1113,13 @@ def arg_min(self) -> Self: ... nw.col("a", "b").arg_min().name.suffix("_arg_min") ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow: + We can then pass any supported library such as Pandas, Polars, or + PyArrow to `agnostic_arg_min`: >>> agnostic_arg_min(df_pd) a_arg_min b_arg_min 0 0 1 + >>> agnostic_arg_min(df_pl) shape: (1, 2) ┌───────────┬───────────┐ @@ -1064,6 +1129,7 @@ def arg_min(self) -> Self: ╞═══════════╪═══════════╡ │ 0 ┆ 1 │ └───────────┴───────────┘ + >>> agnostic_arg_min(df_pa) pyarrow.Table a_arg_min: int64 @@ -1086,9 +1152,11 @@ def arg_max(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [10, 20], "b": [150, 100]}) - >>> df_pl = pl.DataFrame({"a": [10, 20], "b": [150, 100]}) - >>> df_pa = pa.table({"a": [10, 20], "b": [150, 100]}) + >>> + >>> data = {"a": [10, 20], "b": [150, 100]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: @@ -1098,11 +1166,13 @@ def arg_max(self) -> Self: ... nw.col("a", "b").arg_max().name.suffix("_arg_max") ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow: + We can then pass any supported library such as Pandas, Polars, or + PyArrow to `agnostic_arg_max`: >>> agnostic_arg_max(df_pd) a_arg_max b_arg_max 0 1 0 + >>> agnostic_arg_max(df_pl) shape: (1, 2) ┌───────────┬───────────┐ @@ -1112,6 +1182,7 @@ def arg_max(self) -> Self: ╞═══════════╪═══════════╡ │ 1 ┆ 0 │ └───────────┴───────────┘ + >>> agnostic_arg_max(df_pa) pyarrow.Table a_arg_max: int64 @@ -1134,22 +1205,26 @@ def count(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2, 3], "b": [None, 4, 4]}) - >>> df_pl = pl.DataFrame({"a": [1, 2, 3], "b": [None, 4, 4]}) - >>> df_pa = pa.table({"a": [1, 2, 3], "b": [None, 4, 4]}) + >>> + >>> data = {"a": [1, 2, 3], "b": [None, 4, 4]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_count(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.all().count()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_count`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_count(df_pd) a b 0 3 2 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_count(df_pl) shape: (1, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -1158,7 +1233,8 @@ def count(self) -> Self: ╞═════╪═════╡ │ 3 ┆ 2 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_count(df_pa) pyarrow.Table a: int64 b: int64 @@ -1180,22 +1256,25 @@ def n_unique(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2, 3, 4, 5], "b": [1, 1, 3, 3, 5]}) - >>> df_pl = pl.DataFrame({"a": [1, 2, 3, 4, 5], "b": [1, 1, 3, 3, 5]}) - >>> df_pa = pa.table({"a": [1, 2, 3, 4, 5], "b": [1, 1, 3, 3, 5]}) + >>> + >>> data = {"a": [1, 2, 3, 4, 5], "b": [1, 1, 3, 3, 5]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_n_unique(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").n_unique()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_n_unique`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_n_unique(df_pd) a b 0 5 3 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_n_unique(df_pl) shape: (1, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -1204,7 +1283,7 @@ def n_unique(self) -> Self: ╞═════╪═════╡ │ 5 ┆ 3 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_n_unique(df_pa) pyarrow.Table a: int64 b: int64 @@ -1231,24 +1310,28 @@ def unique(self, *, maintain_order: bool = False) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 1, 3, 5, 5], "b": [2, 4, 4, 6, 6]}) - >>> df_pl = pl.DataFrame({"a": [1, 1, 3, 5, 5], "b": [2, 4, 4, 6, 6]}) - >>> df_pa = pa.table({"a": [1, 1, 3, 5, 5], "b": [2, 4, 4, 6, 6]}) + >>> + >>> data = {"a": [1, 1, 3, 5, 5], "b": [2, 4, 4, 6, 6]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_unique(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").unique(maintain_order=True)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_unique`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_unique(df_pd) a b 0 1 2 1 3 4 2 5 6 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_unique(df_pl) shape: (3, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -1259,7 +1342,8 @@ def unique(self, *, maintain_order: bool = False) -> Self: │ 3 ┆ 4 │ │ 5 ┆ 6 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_unique(df_pa) pyarrow.Table a: int64 b: int64 @@ -1283,6 +1367,7 @@ def abs(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, -2], "b": [-3, 4]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -1290,17 +1375,19 @@ def abs(self) -> Self: Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_abs(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").abs()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_abs`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_abs(df_pd) a b 0 1 3 1 2 4 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_abs(df_pl) shape: (2, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -1310,7 +1397,8 @@ def abs(self) -> Self: │ 1 ┆ 3 │ │ 2 ┆ 4 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_abs(df_pa) pyarrow.Table a: int64 b: int64 @@ -1335,26 +1423,29 @@ def cum_sum(self: Self, *, reverse: bool = False) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 1, 3, 5, 5], "b": [2, 4, 4, 6, 6]}) - >>> df_pl = pl.DataFrame({"a": [1, 1, 3, 5, 5], "b": [2, 4, 4, 6, 6]}) - >>> df_pa = pa.table({"a": [1, 1, 3, 5, 5], "b": [2, 4, 4, 6, 6]}) + >>> + >>> data = {"a": [1, 1, 3, 5, 5], "b": [2, 4, 4, 6, 6]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_cum_sum(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a", "b").cum_sum()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_cum_sum`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_cum_sum(df_pd) a b 0 1 2 1 2 6 2 5 10 3 10 16 4 15 22 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_cum_sum(df_pl) shape: (5, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -1367,7 +1458,7 @@ def cum_sum(self: Self, *, reverse: bool = False) -> Self: │ 10 ┆ 16 │ │ 15 ┆ 22 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_cum_sum(df_pa) pyarrow.Table a: int64 b: int64 @@ -1395,31 +1486,35 @@ def diff(self) -> Self: nw.col("a").diff().fill_null(0).cast(nw.Int64) Examples: - >>> import polars as pl >>> import pandas as pd + >>> import polars as pl >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 1, 3, 5, 5]}) - >>> df_pl = pl.DataFrame({"a": [1, 1, 3, 5, 5]}) - >>> df_pa = pa.table({"a": [1, 1, 3, 5, 5]}) + >>> + >>> data = {"a": [1, 1, 3, 5, 5]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_diff(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(a_diff=nw.col("a").diff()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_diff`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_diff(df_pd) a_diff 0 NaN 1 0.0 2 2.0 3 2.0 4 0.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_diff(df_pl) shape: (5, 1) ┌────────┐ │ a_diff │ @@ -1432,7 +1527,8 @@ def diff(self) -> Self: │ 2 │ │ 0 │ └────────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_diff(df_pa) pyarrow.Table a_diff: int64 ---- @@ -1459,31 +1555,35 @@ def shift(self, n: int) -> Self: nw.col("a").shift(1).fill_null(0).cast(nw.Int64) Examples: - >>> import polars as pl >>> import pandas as pd + >>> import polars as pl >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 1, 3, 5, 5]}) - >>> df_pl = pl.DataFrame({"a": [1, 1, 3, 5, 5]}) - >>> df_pa = pa.table({"a": [1, 1, 3, 5, 5]}) + >>> + >>> data = {"a": [1, 1, 3, 5, 5]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_shift(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(a_shift=nw.col("a").shift(n=1)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_shift`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_shift(df_pd) a_shift 0 NaN 1 1.0 2 1.0 3 3.0 4 5.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_shift(df_pl) shape: (5, 1) ┌─────────┐ │ a_shift │ @@ -1496,7 +1596,8 @@ def shift(self, n: int) -> Self: │ 3 │ │ 5 │ └─────────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_shift(df_pa) pyarrow.Table a_shift: int64 ---- @@ -1528,18 +1629,20 @@ def replace_strict( A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa - >>> df_pd = pd.DataFrame({"a": [3, 0, 1, 2]}) - >>> df_pl = pl.DataFrame({"a": [3, 0, 1, 2]}) - >>> df_pa = pa.table({"a": [3, 0, 1, 2]}) + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> + >>> data = {"a": [3, 0, 1, 2]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define dataframe-agnostic functions: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_replace_strict(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... b=nw.col("a").replace_strict( @@ -1549,15 +1652,17 @@ def replace_strict( ... ) ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_replace_strict`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_replace_strict(df_pd) a b 0 3 three 1 0 zero 2 1 one 3 2 two - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_replace_strict(df_pl) shape: (4, 2) ┌─────┬───────┐ │ a ┆ b │ @@ -1569,7 +1674,8 @@ def replace_strict( │ 1 ┆ one │ │ 2 ┆ two │ └─────┴───────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_replace_strict(df_pa) pyarrow.Table a: int64 b: string @@ -1602,35 +1708,38 @@ def sort(self, *, descending: bool = False, nulls_last: bool = False) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa - >>> df_pd = pd.DataFrame({"a": [5, None, 1, 2]}) - >>> df_pl = pl.DataFrame({"a": [5, None, 1, 2]}) - >>> df_pa = pa.table({"a": [5, None, 1, 2]}) + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> + >>> data = {"a": [5, None, 1, 2]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define dataframe-agnostic functions: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_sort(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").sort()).to_native() - >>> def func_descend(df): - ... df = nw.from_native(df) - ... df = df.select(nw.col("a").sort(descending=True)) - ... return nw.to_native(df) + >>> def agnostic_sort_descending(df_native: IntoFrameT) -> IntoFrameT: + ... df = nw.from_native(df_native) + ... return df.select(nw.col("a").sort(descending=True)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_sort` and `agnostic_sort_descending`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_sort(df_pd) a 1 NaN 2 1.0 3 2.0 0 5.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_sort(df_pl) shape: (4, 1) ┌──────┐ │ a │ @@ -1642,19 +1751,21 @@ def sort(self, *, descending: bool = False, nulls_last: bool = False) -> Self: │ 2 │ │ 5 │ └──────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_sort(df_pa) pyarrow.Table a: int64 ---- a: [[null,1,2,5]] - >>> func_descend(df_pd) + >>> agnostic_sort_descending(df_pd) a 1 NaN 0 5.0 3 2.0 2 1.0 - >>> func_descend(df_pl) + + >>> agnostic_sort_descending(df_pl) shape: (4, 1) ┌──────┐ │ a │ @@ -1666,7 +1777,8 @@ def sort(self, *, descending: bool = False, nulls_last: bool = False) -> Self: │ 2 │ │ 1 │ └──────┘ - >>> func_descend(df_pa) + + >>> agnostic_sort_descending(df_pa) pyarrow.Table a: int64 ---- @@ -1701,26 +1813,30 @@ def is_between( >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2, 3, 4, 5]}) - >>> df_pl = pl.DataFrame({"a": [1, 2, 3, 4, 5]}) - >>> df_pa = pa.table({"a": [1, 2, 3, 4, 5]}) + >>> + >>> data = {"a": [1, 2, 3, 4, 5]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_is_between(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").is_between(2, 4, "right")).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_is_between`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_is_between(df_pd) a 0 False 1 False 2 True 3 True 4 False - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_is_between(df_pl) shape: (5, 1) ┌───────┐ │ a │ @@ -1733,7 +1849,8 @@ def is_between( │ true │ │ false │ └───────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_is_between(df_pa) pyarrow.Table a: bool ---- @@ -1762,26 +1879,29 @@ def is_in(self, other: Any) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2, 9, 10]}) - >>> df_pl = pl.DataFrame({"a": [1, 2, 9, 10]}) - >>> df_pa = pa.table({"a": [1, 2, 9, 10]}) + >>> + >>> data = {"a": [1, 2, 9, 10]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_is_in(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns(b=nw.col("a").is_in([1, 2])).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_is_in`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_is_in(df_pd) a b 0 1 True 1 2 True 2 9 False 3 10 False - >>> my_library_agnostic_function(df_pl) + >>> agnostic_is_in(df_pl) shape: (4, 2) ┌─────┬───────┐ │ a ┆ b │ @@ -1793,7 +1913,8 @@ def is_in(self, other: Any) -> Self: │ 9 ┆ false │ │ 10 ┆ false │ └─────┴───────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_is_in(df_pa) pyarrow.Table a: int64 b: bool @@ -1821,32 +1942,36 @@ def filter(self, *predicates: Any) -> Self: A new expression. Examples: - >>> import polars as pl >>> import pandas as pd + >>> import polars as pl >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [2, 3, 4, 5, 6, 7], "b": [10, 11, 12, 13, 14, 15]}) - >>> df_pl = pl.DataFrame({"a": [2, 3, 4, 5, 6, 7], "b": [10, 11, 12, 13, 14, 15]}) - >>> df_pa = pa.table({"a": [2, 3, 4, 5, 6, 7], "b": [10, 11, 12, 13, 14, 15]}) + >>> + >>> data = {"a": [2, 3, 4, 5, 6, 7], "b": [10, 11, 12, 13, 14, 15]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_filter(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("a").filter(nw.col("a") > 4), ... nw.col("b").filter(nw.col("b") < 13), ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_filter`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_filter(df_pd) a b 3 5 10 4 6 11 5 7 12 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_filter(df_pl) shape: (3, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -1857,7 +1982,8 @@ def filter(self, *predicates: Any) -> Self: │ 6 ┆ 11 │ │ 7 ┆ 12 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_filter(df_pa) pyarrow.Table a: int64 b: int64 @@ -1888,13 +2014,19 @@ def is_null(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> df_pd = pd.DataFrame( - ... {"a": [2, 4, None, 3, 5], "b": [2.0, 4.0, float("nan"), 3.0, 5.0]} - ... ) - >>> df_pl = pl.DataFrame( - ... {"a": [2, 4, None, 3, 5], "b": [2.0, 4.0, None, 3.0, 5.0]} + ... { + ... "a": [2, 4, None, 3, 5], + ... "b": [2.0, 4.0, float("nan"), 3.0, 5.0], + ... } ... ) - >>> df_pa = pa.table({"a": [2, 4, None, 3, 5], "b": [2.0, 4.0, None, 3.0, 5.0]}) + >>> data = { + ... "a": [2, 4, None, 3, 5], + ... "b": [2.0, 4.0, None, 3.0, 5.0], + ... } + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: @@ -1904,7 +2036,8 @@ def is_null(self) -> Self: ... a_is_null=nw.col("a").is_null(), b_is_null=nw.col("b").is_null() ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_is_null`: + We can then pass any supported library such as Pandas, Polars, or + PyArrow to `agnostic_is_null`: >>> agnostic_is_null(df_pd) a b a_is_null b_is_null @@ -1959,6 +2092,7 @@ def is_nan(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"orig": [0.0, None, 2.0]} >>> df_pd = pd.DataFrame(data).astype({"orig": "Float64"}) >>> df_pl = pl.DataFrame(data) @@ -1973,7 +2107,8 @@ def is_nan(self) -> Self: ... divided_is_nan=(nw.col("orig") / nw.col("orig")).is_nan(), ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_self_div_is_nan`: + We can then pass any supported library such as Pandas, Polars, or + PyArrow to `agnostic_self_div_is_nan`: >>> print(agnostic_self_div_is_nan(df_pd)) orig divided divided_is_nan @@ -2002,7 +2137,6 @@ def is_nan(self) -> Self: orig: [[0,null,2]] divided: [[nan,null,1]] divided_is_nan: [[true,null,false]] - """ return self.__class__(lambda plx: self._to_compliant_expr(plx).is_nan()) @@ -2018,6 +2152,7 @@ def arg_true(self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, None, None, 2]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2025,17 +2160,19 @@ def arg_true(self) -> Self: We define a library agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_arg_true(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").is_null().arg_true()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_arg_true`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_arg_true(df_pd) a 1 1 2 2 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_arg_true(df_pl) shape: (2, 1) ┌─────┐ │ a │ @@ -2045,7 +2182,8 @@ def arg_true(self) -> Self: │ 1 │ │ 2 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_arg_true(df_pa) pyarrow.Table a: int64 ---- @@ -2080,24 +2218,19 @@ def fill_null( >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> df_pd = pd.DataFrame( ... { ... "a": [2, 4, None, None, 3, 5], ... "b": [2.0, 4.0, float("nan"), float("nan"), 3.0, 5.0], ... } ... ) - >>> df_pl = pl.DataFrame( - ... { - ... "a": [2, 4, None, None, 3, 5], - ... "b": [2.0, 4.0, None, None, 3.0, 5.0], - ... } - ... ) - >>> df_pa = pa.table( - ... { - ... "a": [2, 4, None, None, 3, 5], - ... "b": [2.0, 4.0, None, None, 3.0, 5.0], - ... } - ... ) + >>> data = { + ... "a": [2, 4, None, None, 3, 5], + ... "b": [2.0, 4.0, None, None, 3.0, 5.0], + ... } + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: @@ -2105,7 +2238,8 @@ def fill_null( ... df = nw.from_native(df_native) ... return df.with_columns(nw.col("a", "b").fill_null(0)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_fill_null`: + We can then pass any supported library such as Pandas, Polars, or + PyArrow to `agnostic_fill_null`: >>> agnostic_fill_null(df_pd) a b @@ -2213,12 +2347,12 @@ def drop_nulls(self) -> Self: for reference. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa - + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> df_pd = pd.DataFrame({"a": [2.0, 4.0, float("nan"), 3.0, None, 5.0]}) >>> df_pl = pl.DataFrame({"a": [2.0, 4.0, None, 3.0, None, 5.0]}) >>> df_pa = pa.table({"a": [2.0, 4.0, None, 3.0, None, 5.0]}) @@ -2229,7 +2363,8 @@ def drop_nulls(self) -> Self: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").drop_nulls()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_drop_nulls`: + We can then pass any supported library such as Pandas, Polars, or + PyArrow to `agnostic_drop_nulls`: >>> agnostic_drop_nulls(df_pd) a @@ -2237,6 +2372,7 @@ def drop_nulls(self) -> Self: 1 4.0 3 3.0 5 5.0 + >>> agnostic_drop_nulls(df_pl) shape: (4, 1) ┌─────┐ @@ -2249,6 +2385,7 @@ def drop_nulls(self) -> Self: │ 3.0 │ │ 5.0 │ └─────┘ + >>> agnostic_drop_nulls(df_pa) pyarrow.Table a: double @@ -2278,31 +2415,35 @@ def sample( A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa - >>> df_pd = pd.DataFrame({"a": [1, 2, 3]}) - >>> df_pl = pl.DataFrame({"a": [1, 2, 3]}) - >>> df_pa = pa.table({"a": [1, 2, 3]}) + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> + >>> data = {"a": [1, 2, 3]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_sample(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("a").sample(fraction=1.0, with_replacement=True) ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_sample`: - >>> my_library_agnostic_function(df_pd) # doctest: +SKIP + >>> agnostic_sample(df_pd) # doctest: +SKIP a 2 3 0 1 2 3 - >>> my_library_agnostic_function(df_pl) # doctest: +SKIP + + >>> agnostic_sample(df_pl) # doctest: +SKIP shape: (3, 1) ┌─────┐ │ a │ @@ -2313,7 +2454,8 @@ def sample( │ 3 │ │ 3 │ └─────┘ - >>> my_library_agnostic_function(df_pa) # doctest: +SKIP + + >>> agnostic_sample(df_pa) # doctest: +SKIP pyarrow.Table a: int64 ---- @@ -2337,11 +2479,12 @@ def over(self, *keys: str | Iterable[str]) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3], "b": [1, 1, 2]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2355,13 +2498,15 @@ def over(self, *keys: str | Iterable[str]) -> Self: ... a_min_per_group=nw.col("a").min().over("b") ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_min_over_b`: >>> agnostic_min_over_b(df_pd) a b a_min_per_group 0 1 1 1 1 2 1 1 2 3 2 3 + >>> agnostic_min_over_b(df_pl) shape: (3, 3) ┌─────┬─────┬─────────────────┐ @@ -2373,6 +2518,7 @@ def over(self, *keys: str | Iterable[str]) -> Self: │ 2 ┆ 1 ┆ 1 │ │ 3 ┆ 2 ┆ 3 │ └─────┴─────┴─────────────────┘ + >>> agnostic_min_over_b(df_pa) pyarrow.Table a: int64 @@ -2395,6 +2541,7 @@ def over(self, *keys: str | Iterable[str]) -> Self: 0 1 1 1 1 2 1 3 2 3 2 3 + >>> agnostic_cum_sum(df_pl) shape: (3, 3) ┌─────┬─────┬─────┐ @@ -2418,11 +2565,12 @@ def is_duplicated(self) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3, 1], "b": ["a", "a", "b", "c"]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2430,19 +2578,21 @@ def is_duplicated(self) -> Self: Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_is_duplicated(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.all().is_duplicated()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_is_duplicated`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_is_duplicated(df_pd) a b 0 True True 1 False True 2 False False 3 True False - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_is_duplicated(df_pl) shape: (4, 2) ┌───────┬───────┐ │ a ┆ b │ @@ -2454,7 +2604,8 @@ def is_duplicated(self) -> Self: │ false ┆ false │ │ true ┆ false │ └───────┴───────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_is_duplicated(df_pa) pyarrow.Table a: bool b: bool @@ -2471,11 +2622,12 @@ def is_unique(self) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3, 1], "b": ["a", "a", "b", "c"]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2483,19 +2635,21 @@ def is_unique(self) -> Self: Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_is_unique(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.all().is_unique()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_is_unique`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_is_unique(df_pd) a b 0 False False 1 True False 2 True True 3 False True - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_is_unique(df_pl) shape: (4, 2) ┌───────┬───────┐ │ a ┆ b │ @@ -2507,7 +2661,8 @@ def is_unique(self) -> Self: │ true ┆ true │ │ false ┆ true │ └───────┴───────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_is_unique(df_pa) pyarrow.Table a: bool b: bool @@ -2529,11 +2684,12 @@ def null_count(self) -> Self: for reference. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, None, 1], "b": ["a", None, "b", None]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2545,11 +2701,13 @@ def null_count(self) -> Self: ... df = nw.from_native(df_native) ... return df.select(nw.all().null_count()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_null_count`: + We can then pass any supported library such as Pandas, Polars, or + PyArrow to `agnostic_null_count`: >>> agnostic_null_count(df_pd) a b 0 1 2 + >>> agnostic_null_count(df_pl) shape: (1, 2) ┌─────┬─────┐ @@ -2559,6 +2717,7 @@ def null_count(self) -> Self: ╞═════╪═════╡ │ 1 ┆ 2 │ └─────┴─────┘ + >>> agnostic_null_count(df_pa) pyarrow.Table a: int64 @@ -2576,11 +2735,12 @@ def is_first_distinct(self) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3, 1], "b": ["a", "a", "b", "c"]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2588,19 +2748,21 @@ def is_first_distinct(self) -> Self: Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_is_first_distinct(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.all().is_first_distinct()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_is_first_distinct`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_is_first_distinct(df_pd) a b 0 True True 1 True False 2 True True 3 False True - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_is_first_distinct(df_pl) shape: (4, 2) ┌───────┬───────┐ │ a ┆ b │ @@ -2612,7 +2774,8 @@ def is_first_distinct(self) -> Self: │ true ┆ true │ │ false ┆ true │ └───────┴───────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_is_first_distinct(df_pa) pyarrow.Table a: bool b: bool @@ -2631,11 +2794,12 @@ def is_last_distinct(self) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3, 1], "b": ["a", "a", "b", "c"]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2643,19 +2807,21 @@ def is_last_distinct(self) -> Self: Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_is_last_distinct(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.all().is_last_distinct()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_is_last_distinct`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_is_last_distinct(df_pd) a b 0 False False 1 True True 2 True True 3 True True - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_is_last_distinct(df_pl) shape: (4, 2) ┌───────┬───────┐ │ a ┆ b │ @@ -2667,7 +2833,8 @@ def is_last_distinct(self) -> Self: │ true ┆ true │ │ true ┆ true │ └───────┴───────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_is_last_distinct(df_pa) pyarrow.Table a: bool b: bool @@ -2699,11 +2866,12 @@ def quantile( native 'dask' - method. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": list(range(50)), "b": list(range(50, 100))} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2711,19 +2879,20 @@ def quantile( Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_quantile(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("a", "b").quantile(0.5, interpolation="linear") ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_quantile`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_quantile(df_pd) a b 0 24.5 74.5 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_quantile(df_pl) shape: (1, 2) ┌──────┬──────┐ │ a ┆ b │ @@ -2732,7 +2901,8 @@ def quantile( ╞══════╪══════╡ │ 24.5 ┆ 74.5 │ └──────┴──────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_quantile(df_pa) pyarrow.Table a: double b: double @@ -2754,11 +2924,12 @@ def head(self, n: int = 10) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": list(range(10))} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2766,18 +2937,20 @@ def head(self, n: int = 10) -> Self: Let's define a dataframe-agnostic function that returns the first 3 rows: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_head(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").head(3)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_head`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_head(df_pd) a 0 0 1 1 2 2 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_head(df_pl) shape: (3, 1) ┌─────┐ │ a │ @@ -2788,7 +2961,8 @@ def head(self, n: int = 10) -> Self: │ 1 │ │ 2 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_head(df_pa) pyarrow.Table a: int64 ---- @@ -2806,11 +2980,12 @@ def tail(self, n: int = 10) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": list(range(10))} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2818,18 +2993,20 @@ def tail(self, n: int = 10) -> Self: Let's define a dataframe-agnostic function that returns the last 3 rows: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_tail(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").tail(3)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_tail`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_tail(df_pd) a 7 7 8 8 9 9 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_tail(df_pl) shape: (3, 1) ┌─────┐ │ a │ @@ -2840,7 +3017,8 @@ def tail(self, n: int = 10) -> Self: │ 8 │ │ 9 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_tail(df_pa) pyarrow.Table a: int64 ---- @@ -2867,11 +3045,12 @@ def round(self, decimals: int = 0) -> Self: Polars and Arrow round away from 0 (e.g. -0.5 to -1.0, 0.5 to 1.0, 1.5 to 2.0, 2.5 to 3.0, etc..). Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1.12345, 2.56789, 3.901234]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2879,18 +3058,20 @@ def round(self, decimals: int = 0) -> Self: Let's define a dataframe-agnostic function that rounds to the first decimal: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_round(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").round(1)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_round`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_round(df_pd) a 0 1.1 1 2.6 2 3.9 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_round(df_pl) shape: (3, 1) ┌─────┐ │ a │ @@ -2901,7 +3082,8 @@ def round(self, decimals: int = 0) -> Self: │ 2.6 │ │ 3.9 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_round(df_pa) pyarrow.Table a: double ---- @@ -2918,31 +3100,35 @@ def len(self) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": ["x", "y", "z"], "b": [1, 2, 1]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) >>> df_pa = pa.table(data) - Let's define a dataframe-agnostic function that computes the len over different values of "b" column: + Let's define a dataframe-agnostic function that computes the len over + different values of "b" column: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_len(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("a").filter(nw.col("b") == 1).len().alias("a1"), ... nw.col("a").filter(nw.col("b") == 2).len().alias("a2"), ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_len`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_len(df_pd) a1 a2 0 2 1 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_len(df_pl) shape: (1, 2) ┌─────┬─────┐ │ a1 ┆ a2 │ @@ -2951,7 +3137,8 @@ def len(self) -> Self: ╞═════╪═════╡ │ 2 ┆ 1 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_len(df_pa) pyarrow.Table a1: int64 a2: int64 @@ -2972,11 +3159,12 @@ def gather_every(self: Self, n: int, offset: int = 0) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3, 4], "b": [5, 6, 7, 8]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -2985,17 +3173,19 @@ def gather_every(self: Self, n: int, offset: int = 0) -> Self: Let's define a dataframe-agnostic function in which gather every 2 rows, starting from a offset of 1: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_gather_every(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").gather_every(n=2, offset=1)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_gather_every`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_gather_every(df_pd) a 1 2 3 4 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_gather_every(df_pl) shape: (2, 1) ┌─────┐ │ a │ @@ -3005,7 +3195,8 @@ def gather_every(self: Self, n: int, offset: int = 0) -> Self: │ 2 │ │ 4 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_gather_every(df_pa) pyarrow.Table a: int64 ---- @@ -3037,29 +3228,31 @@ def clip( >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - - >>> s = [1, 2, 3] - >>> df_pd = pd.DataFrame({"s": s}) - >>> df_pl = pl.DataFrame({"s": s}) - >>> df_pa = pa.table({"s": s}) + >>> + >>> data = {"a": [1, 2, 3]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a library agnostic function: - >>> def func_lower(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_clip_lower(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) - ... return df.select(nw.col("s").clip(2)).to_native() + ... return df.select(nw.col("a").clip(2)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func_lower`: + We can then pass any supported library such as Pandas, Polars, or + PyArrow to `agnostic_clip_lower`: - >>> func_lower(df_pd) - s + >>> agnostic_clip_lower(df_pd) + a 0 2 1 2 2 3 - >>> func_lower(df_pl) + + >>> agnostic_clip_lower(df_pl) shape: (3, 1) ┌─────┐ - │ s │ + │ a │ │ --- │ │ i64 │ ╞═════╡ @@ -3067,29 +3260,32 @@ def clip( │ 2 │ │ 3 │ └─────┘ - >>> func_lower(df_pa) + + >>> agnostic_clip_lower(df_pa) pyarrow.Table - s: int64 + a: int64 ---- - s: [[2,2,3]] + a: [[2,2,3]] We define another library agnostic function: - >>> def func_upper(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_clip_upper(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) - ... return df.select(nw.col("s").clip(upper_bound=2)).to_native() + ... return df.select(nw.col("a").clip(upper_bound=2)).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func_upper`: + We can then pass any supported library such as Pandas, Polars, or + PyArrow to `agnostic_clip_upper`: - >>> func_upper(df_pd) - s + >>> agnostic_clip_upper(df_pd) + a 0 1 1 2 2 2 - >>> func_upper(df_pl) + + >>> agnostic_clip_upper(df_pl) shape: (3, 1) ┌─────┐ - │ s │ + │ a │ │ --- │ │ i64 │ ╞═════╡ @@ -3097,39 +3293,42 @@ def clip( │ 2 │ │ 2 │ └─────┘ - >>> func_upper(df_pa) + + >>> agnostic_clip_upper(df_pa) pyarrow.Table - s: int64 + a: int64 ---- - s: [[1,2,2]] + a: [[1,2,2]] We can have both at the same time - >>> s = [-1, 1, -3, 3, -5, 5] - >>> df_pd = pd.DataFrame({"s": s}) - >>> df_pl = pl.DataFrame({"s": s}) - >>> df_pa = pa.table({"s": s}) + >>> data = {"a": [-1, 1, -3, 3, -5, 5]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a library agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_clip(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) - ... return df.select(nw.col("s").clip(-1, 3)).to_native() + ... return df.select(nw.col("a").clip(-1, 3)).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or + PyArrow to `agnostic_clip`: - >>> my_library_agnostic_function(df_pd) - s + >>> agnostic_clip(df_pd) + a 0 -1 1 1 2 -1 3 3 4 -1 5 3 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_clip(df_pl) shape: (6, 1) ┌─────┐ - │ s │ + │ a │ │ --- │ │ i64 │ ╞═════╡ @@ -3140,11 +3339,12 @@ def clip( │ -1 │ │ 3 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_clip(df_pa) pyarrow.Table - s: int64 + a: int64 ---- - s: [[-1,1,-1,3,-1,3]] + a: [[-1,1,-1,3,-1,3]] """ return self.__class__( lambda plx: self._to_compliant_expr(plx).clip( @@ -3167,7 +3367,7 @@ def mode(self: Self) -> Self: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - + >>> >>> data = { ... "a": [1, 1, 2, 3], ... "b": [1, 1, 2, 2], @@ -3178,17 +3378,18 @@ def mode(self: Self) -> Self: We define a library agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_mode(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").mode()).sort("a").to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_mode`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_mode(df_pd) a 0 1 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_mode(df_pl) shape: (1, 1) ┌─────┐ │ a │ @@ -3198,7 +3399,7 @@ def mode(self: Self) -> Self: │ 1 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_mode(df_pa) pyarrow.Table a: int64 ---- @@ -3218,28 +3419,34 @@ def is_finite(self: Self) -> Self: Expression of `Boolean` data type. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [float("nan"), float("inf"), 2.0, None]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a library agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_is_finite(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").is_finite()).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_is_finite`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_is_finite(df_pd) a 0 False 1 False 2 True 3 False - >>> my_library_agnostic_function(pl.DataFrame(data)) + + >>> agnostic_is_finite(df_pl) shape: (4, 1) ┌───────┐ │ a │ @@ -3252,7 +3459,7 @@ def is_finite(self: Self) -> Self: │ null │ └───────┘ - >>> my_library_agnostic_function(pa.table(data)) + >>> agnostic_is_finite(df_pa) pyarrow.Table a: bool ---- @@ -3270,32 +3477,37 @@ def cum_count(self: Self, *, reverse: bool = False) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": ["x", "k", None, "d"]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a library agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_cum_count(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... nw.col("a").cum_count().alias("cum_count"), ... nw.col("a").cum_count(reverse=True).alias("cum_count_reverse"), ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_cum_count`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_cum_count(df_pd) a cum_count cum_count_reverse 0 x 1 3 1 k 2 2 2 None 2 1 3 d 3 1 - >>> my_library_agnostic_function(pl.DataFrame(data)) + >>> agnostic_cum_count(df_pl) shape: (4, 3) ┌──────┬───────────┬───────────────────┐ │ a ┆ cum_count ┆ cum_count_reverse │ @@ -3308,7 +3520,7 @@ def cum_count(self: Self, *, reverse: bool = False) -> Self: │ d ┆ 3 ┆ 1 │ └──────┴───────────┴───────────────────┘ - >>> my_library_agnostic_function(pa.table(data)) + >>> agnostic_cum_count(df_pa) pyarrow.Table a: string cum_count: uint32 @@ -3332,32 +3544,37 @@ def cum_min(self: Self, *, reverse: bool = False) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [3, 1, None, 2]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a library agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_cum_min(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... nw.col("a").cum_min().alias("cum_min"), ... nw.col("a").cum_min(reverse=True).alias("cum_min_reverse"), ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_cum_min`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_cum_min(df_pd) a cum_min cum_min_reverse 0 3.0 3.0 1.0 1 1.0 1.0 1.0 2 NaN NaN NaN 3 2.0 1.0 2.0 - >>> my_library_agnostic_function(pl.DataFrame(data)) + >>> agnostic_cum_min(df_pl) shape: (4, 3) ┌──────┬─────────┬─────────────────┐ │ a ┆ cum_min ┆ cum_min_reverse │ @@ -3370,7 +3587,7 @@ def cum_min(self: Self, *, reverse: bool = False) -> Self: │ 2 ┆ 1 ┆ 2 │ └──────┴─────────┴─────────────────┘ - >>> my_library_agnostic_function(pa.table(data)) + >>> agnostic_cum_min(df_pa) pyarrow.Table a: int64 cum_min: int64 @@ -3394,32 +3611,37 @@ def cum_max(self: Self, *, reverse: bool = False) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 3, None, 2]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a library agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_cum_max(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... nw.col("a").cum_max().alias("cum_max"), ... nw.col("a").cum_max(reverse=True).alias("cum_max_reverse"), ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_cum_max(df_pd) a cum_max cum_max_reverse 0 1.0 1.0 3.0 1 3.0 3.0 3.0 2 NaN NaN NaN 3 2.0 3.0 2.0 - >>> my_library_agnostic_function(pl.DataFrame(data)) + >>> agnostic_cum_max(df_pl) shape: (4, 3) ┌──────┬─────────┬─────────────────┐ │ a ┆ cum_max ┆ cum_max_reverse │ @@ -3432,7 +3654,7 @@ def cum_max(self: Self, *, reverse: bool = False) -> Self: │ 2 ┆ 3 ┆ 2 │ └──────┴─────────┴─────────────────┘ - >>> my_library_agnostic_function(pa.table(data)) + >>> agnostic_cum_max(df_pa) pyarrow.Table a: int64 cum_max: int64 @@ -3456,32 +3678,37 @@ def cum_prod(self: Self, *, reverse: bool = False) -> Self: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 3, None, 2]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a library agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_cum_prod(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... nw.col("a").cum_prod().alias("cum_prod"), ... nw.col("a").cum_prod(reverse=True).alias("cum_prod_reverse"), ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_cum_prod`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_cum_prod(df_pd) a cum_prod cum_prod_reverse 0 1.0 1.0 6.0 1 3.0 3.0 6.0 2 NaN NaN NaN 3 2.0 6.0 2.0 - >>> my_library_agnostic_function(pl.DataFrame(data)) + >>> agnostic_cum_prod(df_pl) shape: (4, 3) ┌──────┬──────────┬──────────────────┐ │ a ┆ cum_prod ┆ cum_prod_reverse │ @@ -3494,7 +3721,7 @@ def cum_prod(self: Self, *, reverse: bool = False) -> Self: │ 2 ┆ 6 ┆ 2 │ └──────┴──────────┴──────────────────┘ - >>> my_library_agnostic_function(pa.table(data)) + >>> agnostic_cum_prod(df_pa) pyarrow.Table a: int64 cum_prod: int64 @@ -3540,11 +3767,12 @@ def rolling_sum( A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1.0, 2.0, None, 4.0]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -3558,7 +3786,8 @@ def rolling_sum( ... b=nw.col("a").rolling_sum(window_size=3, min_periods=1) ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_rolling_sum`: >>> agnostic_rolling_sum(df_pd) a b @@ -3580,7 +3809,7 @@ def rolling_sum( │ 4.0 ┆ 6.0 │ └──────┴─────┘ - >>> agnostic_rolling_sum(df_pa) # doctest:+ELLIPSIS + >>> agnostic_rolling_sum(df_pa) pyarrow.Table a: double b: double @@ -3632,11 +3861,12 @@ def rolling_mean( A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1.0, 2.0, None, 4.0]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -3650,7 +3880,8 @@ def rolling_mean( ... b=nw.col("a").rolling_mean(window_size=3, min_periods=1) ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_rolling_mean`: >>> agnostic_rolling_mean(df_pd) a b @@ -3672,7 +3903,7 @@ def rolling_mean( │ 4.0 ┆ 3.0 │ └──────┴─────┘ - >>> agnostic_rolling_mean(df_pa) # doctest:+ELLIPSIS + >>> agnostic_rolling_mean(df_pa) pyarrow.Table a: double b: double @@ -3726,11 +3957,12 @@ def rolling_var( A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1.0, 2.0, None, 4.0]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -3744,7 +3976,8 @@ def rolling_var( ... b=nw.col("a").rolling_var(window_size=3, min_periods=1) ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_rolling_var`: >>> agnostic_rolling_var(df_pd) a b @@ -3766,7 +3999,7 @@ def rolling_var( │ 4.0 ┆ 2.0 │ └──────┴──────┘ - >>> agnostic_rolling_var(df_pa) # doctest:+ELLIPSIS + >>> agnostic_rolling_var(df_pa) pyarrow.Table a: double b: double @@ -3818,11 +4051,12 @@ def rolling_std( A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1.0, 2.0, None, 4.0]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -3836,7 +4070,8 @@ def rolling_std( ... b=nw.col("a").rolling_std(window_size=3, min_periods=1) ... ).to_native() - We can then pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_rolling_std`: >>> agnostic_rolling_std(df_pd) a b @@ -3858,7 +4093,7 @@ def rolling_std( │ 4.0 ┆ 1.414214 │ └──────┴──────────┘ - >>> agnostic_rolling_std(df_pa) # doctest:+ELLIPSIS + >>> agnostic_rolling_std(df_pa) pyarrow.Table a: double b: double @@ -3918,8 +4153,10 @@ def get_categories(self: Self) -> ExprT: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"fruits": ["apple", "mango", "mango"]} >>> df_pd = pd.DataFrame(data, dtype="category") >>> df_pl = pl.DataFrame(data, schema={"fruits": pl.Categorical}) @@ -3927,17 +4164,19 @@ def get_categories(self: Self) -> ExprT: We define a dataframe-agnostic function to get unique categories from column 'fruits': - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_cat_get_categories(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("fruits").cat.get_categories()).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas or Polars to + `agnostic_cat_get_categories`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_cat_get_categories(df_pd) fruits 0 apple 1 mango - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_cat_get_categories(df_pl) shape: (2, 1) ┌────────┐ │ fruits │ @@ -3966,23 +4205,27 @@ def len_chars(self: Self) -> ExprT: Examples: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"words": ["foo", "Café", "345", "東京", None]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_len_chars(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... words_len=nw.col("words").str.len_chars() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_len_chars`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_len_chars(df_pd) words words_len 0 foo 3.0 1 Café 4.0 @@ -3990,7 +4233,7 @@ def len_chars(self: Self) -> ExprT: 3 東京 2.0 4 None NaN - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_len_chars(df_pl) shape: (5, 2) ┌───────┬───────────┐ │ words ┆ words_len │ @@ -4003,6 +4246,14 @@ def len_chars(self: Self) -> ExprT: │ 東京 ┆ 2 │ │ null ┆ null │ └───────┴───────────┘ + + >>> agnostic_str_len_chars(df_pa) + pyarrow.Table + words: string + words_len: int32 + ---- + words: [["foo","Café","345","東京",null]] + words_len: [[3,4,3,2,null]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).str.len_chars() @@ -4025,27 +4276,31 @@ def replace( Examples: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"foo": ["123abc", "abc abc123"]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_replace(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... df = df.with_columns(replaced=nw.col("foo").str.replace("abc", "")) ... return df.to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_replace`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_replace(df_pd) foo replaced 0 123abc 123 1 abc abc123 abc123 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_replace(df_pl) shape: (2, 2) ┌────────────┬──────────┐ │ foo ┆ replaced │ @@ -4055,6 +4310,14 @@ def replace( │ 123abc ┆ 123 │ │ abc abc123 ┆ abc123 │ └────────────┴──────────┘ + + >>> agnostic_str_replace(df_pa) + pyarrow.Table + foo: string + replaced: string + ---- + foo: [["123abc","abc abc123"]] + replaced: [["123"," abc123"]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).str.replace( @@ -4078,27 +4341,31 @@ def replace_all( Examples: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"foo": ["123abc", "abc abc123"]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_replace_all(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... df = df.with_columns(replaced=nw.col("foo").str.replace_all("abc", "")) ... return df.to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_replace_all`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_replace_all(df_pd) foo replaced 0 123abc 123 1 abc abc123 123 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_replace_all(df_pl) shape: (2, 2) ┌────────────┬──────────┐ │ foo ┆ replaced │ @@ -4108,6 +4375,14 @@ def replace_all( │ 123abc ┆ 123 │ │ abc abc123 ┆ 123 │ └────────────┴──────────┘ + + >>> agnostic_str_replace_all(df_pa) + pyarrow.Table + foo: string + replaced: string + ---- + foo: [["123abc","abc abc123"]] + replaced: [["123"," 123"]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).str.replace_all( @@ -4119,34 +4394,44 @@ def strip_chars(self: Self, characters: str | None = None) -> ExprT: r"""Remove leading and trailing characters. Arguments: - characters: The set of characters to be removed. All combinations of this set of characters will be stripped from the start and end of the string. If set to None (default), all leading and trailing whitespace is removed instead. + characters: The set of characters to be removed. All combinations of this + set of characters will be stripped from the start and end of the string. + If set to None (default), all leading and trailing whitespace is removed + instead. Returns: A new expression. Examples: + >>> from typing import Any >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrame - >>> from typing import Any + >>> >>> data = {"fruits": ["apple", "\nmango"]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrame) -> dict[str, Any]: + >>> def agnostic_str_strip_chars(df_native: IntoFrame) -> dict[str, Any]: ... df = nw.from_native(df_native) ... df = df.with_columns(stripped=nw.col("fruits").str.strip_chars()) ... return df.to_dict(as_series=False) - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_strip_chars`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_strip_chars(df_pd) {'fruits': ['apple', '\nmango'], 'stripped': ['apple', 'mango']} - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_strip_chars(df_pl) + {'fruits': ['apple', '\nmango'], 'stripped': ['apple', 'mango']} + + >>> agnostic_str_strip_chars(df_pa) {'fruits': ['apple', '\nmango'], 'stripped': ['apple', 'mango']} """ return self._expr.__class__( @@ -4165,29 +4450,33 @@ def starts_with(self: Self, prefix: str) -> ExprT: Examples: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"fruits": ["apple", "mango", None]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_starts_with(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... has_prefix=nw.col("fruits").str.starts_with("app") ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_starts_with`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_starts_with(df_pd) fruits has_prefix 0 apple True 1 mango False 2 None None - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_starts_with(df_pl) shape: (3, 2) ┌────────┬────────────┐ │ fruits ┆ has_prefix │ @@ -4198,6 +4487,14 @@ def starts_with(self: Self, prefix: str) -> ExprT: │ mango ┆ false │ │ null ┆ null │ └────────┴────────────┘ + + >>> agnostic_str_starts_with(df_pa) + pyarrow.Table + fruits: string + has_prefix: bool + ---- + fruits: [["apple","mango",null]] + has_prefix: [[true,false,null]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).str.starts_with(prefix) @@ -4215,29 +4512,33 @@ def ends_with(self: Self, suffix: str) -> ExprT: Examples: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"fruits": ["apple", "mango", None]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_ends_with(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... has_suffix=nw.col("fruits").str.ends_with("ngo") ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_ends_with`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_ends_with(df_pd) fruits has_suffix 0 apple False 1 mango True 2 None None - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_ends_with(df_pl) shape: (3, 2) ┌────────┬────────────┐ │ fruits ┆ has_suffix │ @@ -4248,6 +4549,14 @@ def ends_with(self: Self, suffix: str) -> ExprT: │ mango ┆ true │ │ null ┆ null │ └────────┴────────────┘ + + >>> agnostic_str_ends_with(df_pa) + pyarrow.Table + fruits: string + has_suffix: bool + ---- + fruits: [["apple","mango",null]] + has_suffix: [[false,true,null]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).str.ends_with(suffix) @@ -4270,6 +4579,7 @@ def contains(self: Self, pattern: str, *, literal: bool = False) -> ExprT: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"pets": ["cat", "dog", "rabbit and parrot", "dove", None]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -4277,7 +4587,7 @@ def contains(self: Self, pattern: str, *, literal: bool = False) -> ExprT: We define a dataframe-agnostic function: - >>> def agnostic_contains(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_contains(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... default_match=nw.col("pets").str.contains("parrot|Dove"), @@ -4287,9 +4597,10 @@ def contains(self: Self, pattern: str, *, literal: bool = False) -> ExprT: ... ), ... ).to_native() - We can then pass any supported library such as pandas, Polars, or PyArrow to `agnostic_contains`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_contains`: - >>> agnostic_contains(df_pd) + >>> agnostic_str_contains(df_pd) pets default_match case_insensitive_match literal_match 0 cat False False False 1 dog False False False @@ -4297,7 +4608,7 @@ def contains(self: Self, pattern: str, *, literal: bool = False) -> ExprT: 3 dove False True False 4 None None None None - >>> agnostic_contains(df_pl) + >>> agnostic_str_contains(df_pl) shape: (5, 4) ┌───────────────────┬───────────────┬────────────────────────┬───────────────┐ │ pets ┆ default_match ┆ case_insensitive_match ┆ literal_match │ @@ -4311,7 +4622,7 @@ def contains(self: Self, pattern: str, *, literal: bool = False) -> ExprT: │ null ┆ null ┆ null ┆ null │ └───────────────────┴───────────────┴────────────────────────┴───────────────┘ - >>> agnostic_contains(df_pa) + >>> agnostic_str_contains(df_pa) pyarrow.Table pets: string default_match: bool @@ -4343,30 +4654,34 @@ def slice(self: Self, offset: int, length: int | None = None) -> ExprT: Examples: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"s": ["pear", None, "papaya", "dragonfruit"]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_slice(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... s_sliced=nw.col("s").str.slice(4, length=3) ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_slice`: - >>> my_library_agnostic_function(df_pd) # doctest: +NORMALIZE_WHITESPACE + >>> agnostic_str_slice(df_pd) # doctest: +NORMALIZE_WHITESPACE s s_sliced 0 pear 1 None None 2 papaya ya 3 dragonfruit onf - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_slice(df_pl) shape: (4, 2) ┌─────────────┬──────────┐ │ s ┆ s_sliced │ @@ -4379,20 +4694,28 @@ def slice(self: Self, offset: int, length: int | None = None) -> ExprT: │ dragonfruit ┆ onf │ └─────────────┴──────────┘ + >>> agnostic_str_slice(df_pa) + pyarrow.Table + s: string + s_sliced: string + ---- + s: [["pear",null,"papaya","dragonfruit"]] + s_sliced: [["",null,"ya","onf"]] + Using negative indexes: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_slice_negative(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns(s_sliced=nw.col("s").str.slice(-3)).to_native() - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_slice_negative(df_pd) s s_sliced 0 pear ear 1 None None 2 papaya aya 3 dragonfruit uit - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_slice_negative(df_pl) shape: (4, 2) ┌─────────────┬──────────┐ │ s ┆ s_sliced │ @@ -4404,6 +4727,14 @@ def slice(self: Self, offset: int, length: int | None = None) -> ExprT: │ papaya ┆ aya │ │ dragonfruit ┆ uit │ └─────────────┴──────────┘ + + >>> agnostic_str_slice_negative(df_pa) + pyarrow.Table + s: string + s_sliced: string + ---- + s: [["pear",null,"papaya","dragonfruit"]] + s_sliced: [["ear",null,"aya","uit"]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).str.slice( @@ -4426,30 +4757,34 @@ def head(self: Self, n: int = 5) -> ExprT: Examples: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"lyrics": ["Atatata", "taata", "taatatata", "zukkyun"]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_head(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... lyrics_head=nw.col("lyrics").str.head() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_head`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_head(df_pd) lyrics lyrics_head 0 Atatata Atata 1 taata taata 2 taatatata taata 3 zukkyun zukky - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_head(df_pl) shape: (4, 2) ┌───────────┬─────────────┐ │ lyrics ┆ lyrics_head │ @@ -4461,6 +4796,14 @@ def head(self: Self, n: int = 5) -> ExprT: │ taatatata ┆ taata │ │ zukkyun ┆ zukky │ └───────────┴─────────────┘ + + >>> agnostic_str_head(df_pa) + pyarrow.Table + lyrics: string + lyrics_head: string + ---- + lyrics: [["Atatata","taata","taatatata","zukkyun"]] + lyrics_head: [["Atata","taata","taata","zukky"]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).str.slice(0, n) @@ -4481,30 +4824,34 @@ def tail(self: Self, n: int = 5) -> ExprT: Examples: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"lyrics": ["Atatata", "taata", "taatatata", "zukkyun"]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_tail(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... lyrics_tail=nw.col("lyrics").str.tail() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_tail`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_tail(df_pd) lyrics lyrics_tail 0 Atatata atata 1 taata taata 2 taatatata atata 3 zukkyun kkyun - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_tail(df_pl) shape: (4, 2) ┌───────────┬─────────────┐ │ lyrics ┆ lyrics_tail │ @@ -4516,6 +4863,14 @@ def tail(self: Self, n: int = 5) -> ExprT: │ taatatata ┆ atata │ │ zukkyun ┆ kkyun │ └───────────┴─────────────┘ + + >>> agnostic_str_tail(df_pa) + pyarrow.Table + lyrics: string + lyrics_tail: string + ---- + lyrics: [["Atatata","taata","taatatata","zukkyun"]] + lyrics_tail: [["atata","taata","atata","kkyun"]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).str.slice( @@ -4549,6 +4904,7 @@ def to_datetime(self: Self, format: str | None = None) -> ExprT: # noqa: A002 >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = ["2020-01-01", "2020-01-02"] >>> df_pd = pd.DataFrame({"a": data}) >>> df_pl = pl.DataFrame({"a": data}) @@ -4556,19 +4912,21 @@ def to_datetime(self: Self, format: str | None = None) -> ExprT: # noqa: A002 We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_to_datetime(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("a").str.to_datetime(format="%Y-%m-%d") ... ).to_native() - We can then pass any supported library such as pandas, Polars, or PyArrow: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_to_datetime`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_to_datetime(df_pd) a 0 2020-01-01 1 2020-01-02 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_str_to_datetime(df_pl) shape: (2, 1) ┌─────────────────────┐ │ a │ @@ -4578,7 +4936,8 @@ def to_datetime(self: Self, format: str | None = None) -> ExprT: # noqa: A002 │ 2020-01-01 00:00:00 │ │ 2020-01-02 00:00:00 │ └─────────────────────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_str_to_datetime(df_pa) pyarrow.Table a: timestamp[us] ---- @@ -4602,29 +4961,33 @@ def to_uppercase(self: Self) -> ExprT: Examples: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"fruits": ["apple", "mango", None]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_to_uppercase(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... upper_col=nw.col("fruits").str.to_uppercase() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_to_uppercase`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_to_uppercase(df_pd) fruits upper_col 0 apple APPLE 1 mango MANGO 2 None None - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_to_uppercase(df_pl) shape: (3, 2) ┌────────┬───────────┐ │ fruits ┆ upper_col │ @@ -4636,6 +4999,13 @@ def to_uppercase(self: Self) -> ExprT: │ null ┆ null │ └────────┴───────────┘ + >>> agnostic_str_to_uppercase(df_pa) + pyarrow.Table + fruits: string + upper_col: string + ---- + fruits: [["apple","mango",null]] + upper_col: [["APPLE","MANGO",null]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).str.to_uppercase() @@ -4650,29 +5020,33 @@ def to_lowercase(self: Self) -> ExprT: Examples: >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"fruits": ["APPLE", "MANGO", None]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_str_to_lowercase(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... lower_col=nw.col("fruits").str.to_lowercase() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_str_to_lowercase`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_str_to_lowercase(df_pd) fruits lower_col 0 APPLE apple 1 MANGO mango 2 None None - >>> my_library_agnostic_function(df_pl) + >>> agnostic_str_to_lowercase(df_pl) shape: (3, 2) ┌────────┬───────────┐ │ fruits ┆ lower_col │ @@ -4683,6 +5057,14 @@ def to_lowercase(self: Self) -> ExprT: │ MANGO ┆ mango │ │ null ┆ null │ └────────┴───────────┘ + + >>> agnostic_str_to_lowercase(df_pa) + pyarrow.Table + fruits: string + lower_col: string + ---- + fruits: [["APPLE","MANGO",null]] + lower_col: [["apple","mango",null]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).str.to_lowercase() @@ -4703,29 +5085,33 @@ def date(self: Self) -> ExprT: NotImplementedError: If pandas default backend is being used. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [datetime(2012, 1, 7, 10, 20), datetime(2023, 3, 10, 11, 32)]} >>> df_pd = pd.DataFrame(data).convert_dtypes(dtype_backend="pyarrow") >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a library agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_date(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a").dt.date()).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_date`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_date(df_pd) a 0 2012-01-07 1 2023-03-10 - >>> my_library_agnostic_function(df_pl) # docetst + >>> agnostic_dt_date(df_pl) shape: (2, 1) ┌────────────┐ │ a │ @@ -4735,6 +5121,12 @@ def date(self: Self) -> ExprT: │ 2012-01-07 │ │ 2023-03-10 │ └────────────┘ + + >>> agnostic_dt_date(df_pa) + pyarrow.Table + a: date32[day] + ---- + a: [[2012-01-07,2023-03-10]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.date() @@ -4749,11 +5141,13 @@ def year(self: Self) -> ExprT: A new expression. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "datetime": [ ... datetime(1978, 6, 1), @@ -4763,23 +5157,26 @@ def year(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_year(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... nw.col("datetime").dt.year().alias("year") ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_year`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_year(df_pd) datetime year 0 1978-06-01 1978 1 2024-12-13 2024 2 2065-01-01 2065 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_year(df_pl) shape: (3, 2) ┌─────────────────────┬──────┐ │ datetime ┆ year │ @@ -4790,6 +5187,14 @@ def year(self: Self) -> ExprT: │ 2024-12-13 00:00:00 ┆ 2024 │ │ 2065-01-01 00:00:00 ┆ 2065 │ └─────────────────────┴──────┘ + + >>> agnostic_dt_year(df_pa) + pyarrow.Table + datetime: timestamp[us] + year: int64 + ---- + datetime: [[1978-06-01 00:00:00.000000,2024-12-13 00:00:00.000000,2065-01-01 00:00:00.000000]] + year: [[1978,2024,2065]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.year() @@ -4804,11 +5209,13 @@ def month(self: Self) -> ExprT: A new expression. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "datetime": [ ... datetime(1978, 6, 1), @@ -4818,34 +5225,44 @@ def month(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_month(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( - ... nw.col("datetime").dt.year().alias("year"), ... nw.col("datetime").dt.month().alias("month"), ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_month`: - >>> my_library_agnostic_function(df_pd) - datetime year month - 0 1978-06-01 1978 6 - 1 2024-12-13 2024 12 - 2 2065-01-01 2065 1 - >>> my_library_agnostic_function(df_pl) - shape: (3, 3) - ┌─────────────────────┬──────┬───────┐ - │ datetime ┆ year ┆ month │ - │ --- ┆ --- ┆ --- │ - │ datetime[μs] ┆ i32 ┆ i8 │ - ╞═════════════════════╪══════╪═══════╡ - │ 1978-06-01 00:00:00 ┆ 1978 ┆ 6 │ - │ 2024-12-13 00:00:00 ┆ 2024 ┆ 12 │ - │ 2065-01-01 00:00:00 ┆ 2065 ┆ 1 │ - └─────────────────────┴──────┴───────┘ + >>> agnostic_dt_month(df_pd) + datetime month + 0 1978-06-01 6 + 1 2024-12-13 12 + 2 2065-01-01 1 + + >>> agnostic_dt_month(df_pl) + shape: (3, 2) + ┌─────────────────────┬───────┐ + │ datetime ┆ month │ + │ --- ┆ --- │ + │ datetime[μs] ┆ i8 │ + ╞═════════════════════╪═══════╡ + │ 1978-06-01 00:00:00 ┆ 6 │ + │ 2024-12-13 00:00:00 ┆ 12 │ + │ 2065-01-01 00:00:00 ┆ 1 │ + └─────────────────────┴───────┘ + + >>> agnostic_dt_month(df_pa) + pyarrow.Table + datetime: timestamp[us] + month: int64 + ---- + datetime: [[1978-06-01 00:00:00.000000,2024-12-13 00:00:00.000000,2065-01-01 00:00:00.000000]] + month: [[6,12,1]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.month() @@ -4860,11 +5277,13 @@ def day(self: Self) -> ExprT: A new expression. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "datetime": [ ... datetime(1978, 6, 1), @@ -4874,35 +5293,44 @@ def day(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_day(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( - ... nw.col("datetime").dt.year().alias("year"), - ... nw.col("datetime").dt.month().alias("month"), ... nw.col("datetime").dt.day().alias("day"), ... ).to_native() - We can then pass either pandas or Polars to `func`: - - >>> my_library_agnostic_function(df_pd) - datetime year month day - 0 1978-06-01 1978 6 1 - 1 2024-12-13 2024 12 13 - 2 2065-01-01 2065 1 1 - >>> my_library_agnostic_function(df_pl) - shape: (3, 4) - ┌─────────────────────┬──────┬───────┬─────┐ - │ datetime ┆ year ┆ month ┆ day │ - │ --- ┆ --- ┆ --- ┆ --- │ - │ datetime[μs] ┆ i32 ┆ i8 ┆ i8 │ - ╞═════════════════════╪══════╪═══════╪═════╡ - │ 1978-06-01 00:00:00 ┆ 1978 ┆ 6 ┆ 1 │ - │ 2024-12-13 00:00:00 ┆ 2024 ┆ 12 ┆ 13 │ - │ 2065-01-01 00:00:00 ┆ 2065 ┆ 1 ┆ 1 │ - └─────────────────────┴──────┴───────┴─────┘ + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_day`: + + >>> agnostic_dt_day(df_pd) + datetime day + 0 1978-06-01 1 + 1 2024-12-13 13 + 2 2065-01-01 1 + + >>> agnostic_dt_day(df_pl) + shape: (3, 2) + ┌─────────────────────┬─────┐ + │ datetime ┆ day │ + │ --- ┆ --- │ + │ datetime[μs] ┆ i8 │ + ╞═════════════════════╪═════╡ + │ 1978-06-01 00:00:00 ┆ 1 │ + │ 2024-12-13 00:00:00 ┆ 13 │ + │ 2065-01-01 00:00:00 ┆ 1 │ + └─────────────────────┴─────┘ + + >>> agnostic_dt_day(df_pa) + pyarrow.Table + datetime: timestamp[us] + day: int64 + ---- + datetime: [[1978-06-01 00:00:00.000000,2024-12-13 00:00:00.000000,2065-01-01 00:00:00.000000]] + day: [[1,13,1]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.day() @@ -4917,11 +5345,13 @@ def hour(self: Self) -> ExprT: A new expression. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "datetime": [ ... datetime(1978, 1, 1, 1), @@ -4931,23 +5361,26 @@ def hour(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_hour(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... nw.col("datetime").dt.hour().alias("hour") ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_hour`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_hour(df_pd) datetime hour 0 1978-01-01 01:00:00 1 1 2024-10-13 05:00:00 5 2 2065-01-01 10:00:00 10 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_hour(df_pl) shape: (3, 2) ┌─────────────────────┬──────┐ │ datetime ┆ hour │ @@ -4958,6 +5391,14 @@ def hour(self: Self) -> ExprT: │ 2024-10-13 05:00:00 ┆ 5 │ │ 2065-01-01 10:00:00 ┆ 10 │ └─────────────────────┴──────┘ + + >>> agnostic_dt_hour(df_pa) + pyarrow.Table + datetime: timestamp[us] + hour: int64 + ---- + datetime: [[1978-01-01 01:00:00.000000,2024-10-13 05:00:00.000000,2065-01-01 10:00:00.000000]] + hour: [[1,5,10]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.hour() @@ -4972,11 +5413,13 @@ def minute(self: Self) -> ExprT: A new expression. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "datetime": [ ... datetime(1978, 1, 1, 1, 1), @@ -4986,34 +5429,44 @@ def minute(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_minute(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( - ... nw.col("datetime").dt.hour().alias("hour"), ... nw.col("datetime").dt.minute().alias("minute"), ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_minute`: - >>> my_library_agnostic_function(df_pd) - datetime hour minute - 0 1978-01-01 01:01:00 1 1 - 1 2024-10-13 05:30:00 5 30 - 2 2065-01-01 10:20:00 10 20 - >>> my_library_agnostic_function(df_pl) - shape: (3, 3) - ┌─────────────────────┬──────┬────────┐ - │ datetime ┆ hour ┆ minute │ - │ --- ┆ --- ┆ --- │ - │ datetime[μs] ┆ i8 ┆ i8 │ - ╞═════════════════════╪══════╪════════╡ - │ 1978-01-01 01:01:00 ┆ 1 ┆ 1 │ - │ 2024-10-13 05:30:00 ┆ 5 ┆ 30 │ - │ 2065-01-01 10:20:00 ┆ 10 ┆ 20 │ - └─────────────────────┴──────┴────────┘ + >>> agnostic_dt_minute(df_pd) + datetime minute + 0 1978-01-01 01:01:00 1 + 1 2024-10-13 05:30:00 30 + 2 2065-01-01 10:20:00 20 + + >>> agnostic_dt_minute(df_pl) + shape: (3, 2) + ┌─────────────────────┬────────┐ + │ datetime ┆ minute │ + │ --- ┆ --- │ + │ datetime[μs] ┆ i8 │ + ╞═════════════════════╪════════╡ + │ 1978-01-01 01:01:00 ┆ 1 │ + │ 2024-10-13 05:30:00 ┆ 30 │ + │ 2065-01-01 10:20:00 ┆ 20 │ + └─────────────────────┴────────┘ + + >>> agnostic_dt_minute(df_pa) + pyarrow.Table + datetime: timestamp[us] + minute: int64 + ---- + datetime: [[1978-01-01 01:01:00.000000,2024-10-13 05:30:00.000000,2065-01-01 10:20:00.000000]] + minute: [[1,30,20]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.minute() @@ -5026,11 +5479,13 @@ def second(self: Self) -> ExprT: A new expression. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "datetime": [ ... datetime(1978, 1, 1, 1, 1, 1), @@ -5040,35 +5495,44 @@ def second(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_second(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( - ... nw.col("datetime").dt.hour().alias("hour"), - ... nw.col("datetime").dt.minute().alias("minute"), ... nw.col("datetime").dt.second().alias("second"), ... ).to_native() - We can then pass either pandas or Polars to `func`: - - >>> my_library_agnostic_function(df_pd) - datetime hour minute second - 0 1978-01-01 01:01:01 1 1 1 - 1 2024-10-13 05:30:14 5 30 14 - 2 2065-01-01 10:20:30 10 20 30 - >>> my_library_agnostic_function(df_pl) - shape: (3, 4) - ┌─────────────────────┬──────┬────────┬────────┐ - │ datetime ┆ hour ┆ minute ┆ second │ - │ --- ┆ --- ┆ --- ┆ --- │ - │ datetime[μs] ┆ i8 ┆ i8 ┆ i8 │ - ╞═════════════════════╪══════╪════════╪════════╡ - │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1 │ - │ 2024-10-13 05:30:14 ┆ 5 ┆ 30 ┆ 14 │ - │ 2065-01-01 10:20:30 ┆ 10 ┆ 20 ┆ 30 │ - └─────────────────────┴──────┴────────┴────────┘ + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_second`: + + >>> agnostic_dt_second(df_pd) + datetime second + 0 1978-01-01 01:01:01 1 + 1 2024-10-13 05:30:14 14 + 2 2065-01-01 10:20:30 30 + + >>> agnostic_dt_second(df_pl) + shape: (3, 2) + ┌─────────────────────┬────────┐ + │ datetime ┆ second │ + │ --- ┆ --- │ + │ datetime[μs] ┆ i8 │ + ╞═════════════════════╪════════╡ + │ 1978-01-01 01:01:01 ┆ 1 │ + │ 2024-10-13 05:30:14 ┆ 14 │ + │ 2065-01-01 10:20:30 ┆ 30 │ + └─────────────────────┴────────┘ + + >>> agnostic_dt_second(df_pa) + pyarrow.Table + datetime: timestamp[us] + second: int64 + ---- + datetime: [[1978-01-01 01:01:01.000000,2024-10-13 05:30:14.000000,2065-01-01 10:20:30.000000]] + second: [[1,14,30]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.second() @@ -5081,11 +5545,13 @@ def millisecond(self: Self) -> ExprT: A new expression. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "datetime": [ ... datetime(1978, 1, 1, 1, 1, 1, 0), @@ -5095,36 +5561,44 @@ def millisecond(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_millisecond(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( - ... nw.col("datetime").dt.hour().alias("hour"), - ... nw.col("datetime").dt.minute().alias("minute"), - ... nw.col("datetime").dt.second().alias("second"), ... nw.col("datetime").dt.millisecond().alias("millisecond"), ... ).to_native() - We can then pass either pandas or Polars to `func`: - - >>> my_library_agnostic_function(df_pd) - datetime hour minute second millisecond - 0 1978-01-01 01:01:01.000 1 1 1 0 - 1 2024-10-13 05:30:14.505 5 30 14 505 - 2 2065-01-01 10:20:30.067 10 20 30 67 - >>> my_library_agnostic_function(df_pl) - shape: (3, 5) - ┌─────────────────────────┬──────┬────────┬────────┬─────────────┐ - │ datetime ┆ hour ┆ minute ┆ second ┆ millisecond │ - │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ - │ datetime[μs] ┆ i8 ┆ i8 ┆ i8 ┆ i32 │ - ╞═════════════════════════╪══════╪════════╪════════╪═════════════╡ - │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1 ┆ 0 │ - │ 2024-10-13 05:30:14.505 ┆ 5 ┆ 30 ┆ 14 ┆ 505 │ - │ 2065-01-01 10:20:30.067 ┆ 10 ┆ 20 ┆ 30 ┆ 67 │ - └─────────────────────────┴──────┴────────┴────────┴─────────────┘ + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_millisecond`: + + >>> agnostic_dt_millisecond(df_pd) + datetime millisecond + 0 1978-01-01 01:01:01.000 0 + 1 2024-10-13 05:30:14.505 505 + 2 2065-01-01 10:20:30.067 67 + + >>> agnostic_dt_millisecond(df_pl) + shape: (3, 2) + ┌─────────────────────────┬─────────────┐ + │ datetime ┆ millisecond │ + │ --- ┆ --- │ + │ datetime[μs] ┆ i32 │ + ╞═════════════════════════╪═════════════╡ + │ 1978-01-01 01:01:01 ┆ 0 │ + │ 2024-10-13 05:30:14.505 ┆ 505 │ + │ 2065-01-01 10:20:30.067 ┆ 67 │ + └─────────────────────────┴─────────────┘ + + >>> agnostic_dt_millisecond(df_pa) + pyarrow.Table + datetime: timestamp[us] + millisecond: int64 + ---- + datetime: [[1978-01-01 01:01:01.000000,2024-10-13 05:30:14.505000,2065-01-01 10:20:30.067000]] + millisecond: [[0,505,67]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.millisecond() @@ -5137,11 +5611,13 @@ def microsecond(self: Self) -> ExprT: A new expression. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "datetime": [ ... datetime(1978, 1, 1, 1, 1, 1, 0), @@ -5151,36 +5627,44 @@ def microsecond(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_microsecond(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( - ... nw.col("datetime").dt.hour().alias("hour"), - ... nw.col("datetime").dt.minute().alias("minute"), - ... nw.col("datetime").dt.second().alias("second"), ... nw.col("datetime").dt.microsecond().alias("microsecond"), ... ).to_native() - We can then pass either pandas or Polars to `func`: - - >>> my_library_agnostic_function(df_pd) - datetime hour minute second microsecond - 0 1978-01-01 01:01:01.000 1 1 1 0 - 1 2024-10-13 05:30:14.505 5 30 14 505000 - 2 2065-01-01 10:20:30.067 10 20 30 67000 - >>> my_library_agnostic_function(df_pl) - shape: (3, 5) - ┌─────────────────────────┬──────┬────────┬────────┬─────────────┐ - │ datetime ┆ hour ┆ minute ┆ second ┆ microsecond │ - │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ - │ datetime[μs] ┆ i8 ┆ i8 ┆ i8 ┆ i32 │ - ╞═════════════════════════╪══════╪════════╪════════╪═════════════╡ - │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1 ┆ 0 │ - │ 2024-10-13 05:30:14.505 ┆ 5 ┆ 30 ┆ 14 ┆ 505000 │ - │ 2065-01-01 10:20:30.067 ┆ 10 ┆ 20 ┆ 30 ┆ 67000 │ - └─────────────────────────┴──────┴────────┴────────┴─────────────┘ + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_microsecond`: + + >>> agnostic_dt_microsecond(df_pd) + datetime microsecond + 0 1978-01-01 01:01:01.000 0 + 1 2024-10-13 05:30:14.505 505000 + 2 2065-01-01 10:20:30.067 67000 + + >>> agnostic_dt_microsecond(df_pl) + shape: (3, 2) + ┌─────────────────────────┬─────────────┐ + │ datetime ┆ microsecond │ + │ --- ┆ --- │ + │ datetime[μs] ┆ i32 │ + ╞═════════════════════════╪═════════════╡ + │ 1978-01-01 01:01:01 ┆ 0 │ + │ 2024-10-13 05:30:14.505 ┆ 505000 │ + │ 2065-01-01 10:20:30.067 ┆ 67000 │ + └─────────────────────────┴─────────────┘ + + >>> agnostic_dt_microsecond(df_pa) + pyarrow.Table + datetime: timestamp[us] + microsecond: int64 + ---- + datetime: [[1978-01-01 01:01:01.000000,2024-10-13 05:30:14.505000,2065-01-01 10:20:30.067000]] + microsecond: [[0,505000,67000]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.microsecond() @@ -5193,11 +5677,13 @@ def nanosecond(self: Self) -> ExprT: A new expression. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "datetime": [ ... datetime(1978, 1, 1, 1, 1, 1, 0), @@ -5207,36 +5693,44 @@ def nanosecond(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_nanosecond(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( - ... nw.col("datetime").dt.hour().alias("hour"), - ... nw.col("datetime").dt.minute().alias("minute"), - ... nw.col("datetime").dt.second().alias("second"), ... nw.col("datetime").dt.nanosecond().alias("nanosecond"), ... ).to_native() - We can then pass either pandas or Polars to `func`: - - >>> my_library_agnostic_function(df_pd) - datetime hour minute second nanosecond - 0 1978-01-01 01:01:01.000 1 1 1 0 - 1 2024-10-13 05:30:14.500 5 30 14 500000000 - 2 2065-01-01 10:20:30.060 10 20 30 60000000 - >>> my_library_agnostic_function(df_pl) - shape: (3, 5) - ┌─────────────────────────┬──────┬────────┬────────┬────────────┐ - │ datetime ┆ hour ┆ minute ┆ second ┆ nanosecond │ - │ --- ┆ --- ┆ --- ┆ --- ┆ --- │ - │ datetime[μs] ┆ i8 ┆ i8 ┆ i8 ┆ i32 │ - ╞═════════════════════════╪══════╪════════╪════════╪════════════╡ - │ 1978-01-01 01:01:01 ┆ 1 ┆ 1 ┆ 1 ┆ 0 │ - │ 2024-10-13 05:30:14.500 ┆ 5 ┆ 30 ┆ 14 ┆ 500000000 │ - │ 2065-01-01 10:20:30.060 ┆ 10 ┆ 20 ┆ 30 ┆ 60000000 │ - └─────────────────────────┴──────┴────────┴────────┴────────────┘ + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_nanosecond`: + + >>> agnostic_dt_nanosecond(df_pd) + datetime nanosecond + 0 1978-01-01 01:01:01.000 0 + 1 2024-10-13 05:30:14.500 500000000 + 2 2065-01-01 10:20:30.060 60000000 + + >>> agnostic_dt_nanosecond(df_pl) + shape: (3, 2) + ┌─────────────────────────┬────────────┐ + │ datetime ┆ nanosecond │ + │ --- ┆ --- │ + │ datetime[μs] ┆ i32 │ + ╞═════════════════════════╪════════════╡ + │ 1978-01-01 01:01:01 ┆ 0 │ + │ 2024-10-13 05:30:14.500 ┆ 500000000 │ + │ 2065-01-01 10:20:30.060 ┆ 60000000 │ + └─────────────────────────┴────────────┘ + + >>> agnostic_dt_nanosecond(df_pa) + pyarrow.Table + datetime: timestamp[us] + nanosecond: int64 + ---- + datetime: [[1978-01-01 01:01:01.000000,2024-10-13 05:30:14.500000,2065-01-01 10:20:30.060000]] + nanosecond: [[0,500000000,60000000]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.nanosecond() @@ -5249,30 +5743,35 @@ def ordinal_day(self: Self) -> ExprT: A new expression. Examples: + >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl - >>> from datetime import datetime + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [datetime(2020, 1, 1), datetime(2020, 8, 3)]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_ordinal_day(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... a_ordinal_day=nw.col("a").dt.ordinal_day() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_ordinal_day`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_ordinal_day(df_pd) a a_ordinal_day 0 2020-01-01 1 1 2020-08-03 216 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_ordinal_day(df_pl) shape: (2, 2) ┌─────────────────────┬───────────────┐ │ a ┆ a_ordinal_day │ @@ -5282,6 +5781,14 @@ def ordinal_day(self: Self) -> ExprT: │ 2020-01-01 00:00:00 ┆ 1 │ │ 2020-08-03 00:00:00 ┆ 216 │ └─────────────────────┴───────────────┘ + + >>> agnostic_dt_ordinal_day(df_pa) + pyarrow.Table + a: timestamp[us] + a_ordinal_day: int64 + ---- + a: [[2020-01-01 00:00:00.000000,2020-08-03 00:00:00.000000]] + a_ordinal_day: [[1,216]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.ordinal_day() @@ -5293,7 +5800,6 @@ def weekday(self: Self) -> ExprT: Returns: Returns the ISO weekday number where monday = 1 and sunday = 7 - Examples: >>> from datetime import datetime >>> import pandas as pd @@ -5301,6 +5807,7 @@ def weekday(self: Self) -> ExprT: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [datetime(2020, 1, 1), datetime(2020, 8, 3)]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) @@ -5308,17 +5815,19 @@ def weekday(self: Self) -> ExprT: We define a dataframe-agnostic function: - >>> def agnostic_weekday(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_weekday(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns(a_weekday=nw.col("a").dt.weekday()).to_native() - We can then pass either pandas, Polars, PyArrow, and other supported libraries to `agnostic_weekday`: + We can then pass either pandas, Polars, PyArrow, and other supported libraries to + `agnostic_dt_weekday`: - >>> agnostic_weekday(df_pd) + >>> agnostic_dt_weekday(df_pd) a a_weekday 0 2020-01-01 3 1 2020-08-03 1 - >>> agnostic_weekday(df_pl) + + >>> agnostic_dt_weekday(df_pl) shape: (2, 2) ┌─────────────────────┬───────────┐ │ a ┆ a_weekday │ @@ -5328,7 +5837,8 @@ def weekday(self: Self) -> ExprT: │ 2020-01-01 00:00:00 ┆ 3 │ │ 2020-08-03 00:00:00 ┆ 1 │ └─────────────────────┴───────────┘ - >>> agnostic_weekday(df_pa) + + >>> agnostic_dt_weekday(df_pa) pyarrow.Table a: timestamp[us] a_weekday: int64 @@ -5352,30 +5862,35 @@ def total_minutes(self: Self) -> ExprT: consider using `fill_null()` and `cast` in this case. Examples: + >>> from datetime import timedelta >>> import pandas as pd >>> import polars as pl - >>> from datetime import timedelta + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [timedelta(minutes=10), timedelta(minutes=20, seconds=40)]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_total_minutes(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... a_total_minutes=nw.col("a").dt.total_minutes() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_total_minutes`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_total_minutes(df_pd) a a_total_minutes 0 0 days 00:10:00 10 1 0 days 00:20:40 20 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_total_minutes(df_pl) shape: (2, 2) ┌──────────────┬─────────────────┐ │ a ┆ a_total_minutes │ @@ -5385,6 +5900,14 @@ def total_minutes(self: Self) -> ExprT: │ 10m ┆ 10 │ │ 20m 40s ┆ 20 │ └──────────────┴─────────────────┘ + + >>> agnostic_dt_total_minutes(df_pa) + pyarrow.Table + a: duration[us] + a_total_minutes: int64 + ---- + a: [[600000000,1240000000]] + a_total_minutes: [[10,20]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.total_minutes() @@ -5402,30 +5925,35 @@ def total_seconds(self: Self) -> ExprT: consider using `fill_null()` and `cast` in this case. Examples: + >>> from datetime import timedelta >>> import pandas as pd >>> import polars as pl - >>> from datetime import timedelta + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [timedelta(seconds=10), timedelta(seconds=20, milliseconds=40)]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_total_seconds(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... a_total_seconds=nw.col("a").dt.total_seconds() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_total_seconds`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_total_seconds(df_pd) a a_total_seconds 0 0 days 00:00:10 10 1 0 days 00:00:20.040000 20 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_total_seconds(df_pl) shape: (2, 2) ┌──────────────┬─────────────────┐ │ a ┆ a_total_seconds │ @@ -5435,6 +5963,14 @@ def total_seconds(self: Self) -> ExprT: │ 10s ┆ 10 │ │ 20s 40ms ┆ 20 │ └──────────────┴─────────────────┘ + + >>> agnostic_dt_total_seconds(df_pa) + pyarrow.Table + a: duration[us] + a_total_seconds: int64 + ---- + a: [[10000000,20040000]] + a_total_seconds: [[10,20]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.total_seconds() @@ -5452,11 +5988,13 @@ def total_milliseconds(self: Self) -> ExprT: consider using `fill_null()` and `cast` in this case. Examples: + >>> from datetime import timedelta >>> import pandas as pd >>> import polars as pl - >>> from datetime import timedelta + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [ ... timedelta(milliseconds=10), @@ -5465,22 +6003,25 @@ def total_milliseconds(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_total_milliseconds(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... a_total_milliseconds=nw.col("a").dt.total_milliseconds() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_total_milliseconds`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_total_milliseconds(df_pd) a a_total_milliseconds 0 0 days 00:00:00.010000 10 1 0 days 00:00:00.020040 20 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_total_milliseconds(df_pl) shape: (2, 2) ┌──────────────┬──────────────────────┐ │ a ┆ a_total_milliseconds │ @@ -5490,6 +6031,14 @@ def total_milliseconds(self: Self) -> ExprT: │ 10ms ┆ 10 │ │ 20040µs ┆ 20 │ └──────────────┴──────────────────────┘ + + >>> agnostic_dt_total_milliseconds(df_pa) + pyarrow.Table + a: duration[us] + a_total_milliseconds: int64 + ---- + a: [[10000,20040]] + a_total_milliseconds: [[10,20]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.total_milliseconds() @@ -5507,11 +6056,13 @@ def total_microseconds(self: Self) -> ExprT: consider using `fill_null()` and `cast` in this case. Examples: + >>> from datetime import timedelta >>> import pandas as pd >>> import polars as pl - >>> from datetime import timedelta + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [ ... timedelta(microseconds=10), @@ -5520,22 +6071,25 @@ def total_microseconds(self: Self) -> ExprT: ... } >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_total_microseconds(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... a_total_microseconds=nw.col("a").dt.total_microseconds() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_total_microseconds`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_total_microseconds(df_pd) a a_total_microseconds 0 0 days 00:00:00.000010 10 1 0 days 00:00:00.001200 1200 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_total_microseconds(df_pl) shape: (2, 2) ┌──────────────┬──────────────────────┐ │ a ┆ a_total_microseconds │ @@ -5545,6 +6099,14 @@ def total_microseconds(self: Self) -> ExprT: │ 10µs ┆ 10 │ │ 1200µs ┆ 1200 │ └──────────────┴──────────────────────┘ + + >>> agnostic_dt_total_microseconds(df_pa) + pyarrow.Table + a: duration[us] + a_total_microseconds: int64 + ---- + a: [[10,1200]] + a_total_microseconds: [[10,1200]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.total_microseconds() @@ -5562,11 +6124,12 @@ def total_nanoseconds(self: Self) -> ExprT: consider using `fill_null()` and `cast` in this case. Examples: + >>> from datetime import timedelta >>> import pandas as pd >>> import polars as pl - >>> from datetime import timedelta >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = ["2024-01-01 00:00:00.000000001", "2024-01-01 00:00:00.000000002"] >>> df_pd = pd.DataFrame({"a": pd.to_datetime(data)}) >>> df_pl = pl.DataFrame({"a": data}).with_columns( @@ -5575,19 +6138,21 @@ def total_nanoseconds(self: Self) -> ExprT: We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_total_nanoseconds(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... a_diff_total_nanoseconds=nw.col("a").diff().dt.total_nanoseconds() ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_total_nanoseconds`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_total_nanoseconds(df_pd) a a_diff_total_nanoseconds 0 2024-01-01 00:00:00.000000001 NaN 1 2024-01-01 00:00:00.000000002 1.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_total_nanoseconds(df_pl) shape: (2, 2) ┌───────────────────────────────┬──────────────────────────┐ │ a ┆ a_diff_total_nanoseconds │ @@ -5646,33 +6211,39 @@ def to_string(self: Self, format: str) -> ExprT: # noqa: A002 >>> from datetime import datetime >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> data = [ - ... datetime(2020, 3, 1), - ... datetime(2020, 4, 1), - ... datetime(2020, 5, 1), - ... ] - >>> df_pd = pd.DataFrame({"a": data}) - >>> df_pl = pl.DataFrame({"a": data}) + >>> + >>> data = { + ... "a": [ + ... datetime(2020, 3, 1), + ... datetime(2020, 4, 1), + ... datetime(2020, 5, 1), + ... ] + ... } + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_to_string(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("a").dt.to_string("%Y/%m/%d %H:%M:%S") ... ).to_native() - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_to_string`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_to_string(df_pd) a 0 2020/03/01 00:00:00 1 2020/04/01 00:00:00 2 2020/05/01 00:00:00 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_dt_to_string(df_pl) shape: (3, 1) ┌─────────────────────┐ │ a │ @@ -5683,6 +6254,12 @@ def to_string(self: Self, format: str) -> ExprT: # noqa: A002 │ 2020/04/01 00:00:00 │ │ 2020/05/01 00:00:00 │ └─────────────────────┘ + + >>> agnostic_dt_to_string(df_pa) + pyarrow.Table + a: string + ---- + a: [["2020/03/01 00:00:00.000000","2020/04/01 00:00:00.000000","2020/05/01 00:00:00.000000"]] """ return self._expr.__class__( lambda plx: self._expr._to_compliant_expr(plx).dt.to_string(format) @@ -5699,11 +6276,12 @@ def replace_time_zone(self: Self, time_zone: str | None) -> ExprT: Examples: >>> from datetime import datetime, timezone - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [ ... datetime(2024, 1, 1, tzinfo=timezone.utc), @@ -5716,19 +6294,21 @@ def replace_time_zone(self: Self, time_zone: str | None) -> ExprT: Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_replace_time_zone(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("a").dt.replace_time_zone("Asia/Kathmandu") ... ).to_native() - We can then pass pandas / PyArrow / Polars / any other supported library: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_replace_time_zone`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_replace_time_zone(df_pd) a 0 2024-01-01 00:00:00+05:45 1 2024-01-02 00:00:00+05:45 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_replace_time_zone(df_pl) shape: (2, 1) ┌──────────────────────────────┐ │ a │ @@ -5738,7 +6318,8 @@ def replace_time_zone(self: Self, time_zone: str | None) -> ExprT: │ 2024-01-01 00:00:00 +0545 │ │ 2024-01-02 00:00:00 +0545 │ └──────────────────────────────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_dt_replace_time_zone(df_pa) pyarrow.Table a: timestamp[us, tz=Asia/Kathmandu] ---- @@ -5762,11 +6343,12 @@ def convert_time_zone(self: Self, time_zone: str) -> ExprT: Examples: >>> from datetime import datetime, timezone - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [ ... datetime(2024, 1, 1, tzinfo=timezone.utc), @@ -5779,19 +6361,21 @@ def convert_time_zone(self: Self, time_zone: str) -> ExprT: Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_convert_time_zone(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.col("a").dt.convert_time_zone("Asia/Kathmandu") ... ).to_native() - We can then pass pandas / PyArrow / Polars / any other supported library: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_convert_time_zone`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_convert_time_zone(df_pd) a 0 2024-01-01 05:45:00+05:45 1 2024-01-02 05:45:00+05:45 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_convert_time_zone(df_pl) shape: (2, 1) ┌──────────────────────────────┐ │ a │ @@ -5801,7 +6385,8 @@ def convert_time_zone(self: Self, time_zone: str) -> ExprT: │ 2024-01-01 05:45:00 +0545 │ │ 2024-01-02 05:45:00 +0545 │ └──────────────────────────────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_dt_convert_time_zone(df_pa) pyarrow.Table a: timestamp[us, tz=Asia/Kathmandu] ---- @@ -5826,11 +6411,12 @@ def timestamp(self: Self, time_unit: Literal["ns", "us", "ms"] = "us") -> ExprT: Examples: >>> from datetime import date - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"date": [date(2001, 1, 1), None, date(2001, 1, 3)]} >>> df_pd = pd.DataFrame(data, dtype="datetime64[ns]") >>> df_pl = pl.DataFrame(data) @@ -5838,21 +6424,23 @@ def timestamp(self: Self, time_unit: Literal["ns", "us", "ms"] = "us") -> ExprT: Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_dt_timestamp(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... nw.col("date").dt.timestamp().alias("timestamp_us"), ... nw.col("date").dt.timestamp("ms").alias("timestamp_ms"), ... ).to_native() - We can then pass pandas / PyArrow / Polars / any other supported library: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_dt_timestamp`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_dt_timestamp(df_pd) date timestamp_us timestamp_ms 0 2001-01-01 9.783072e+14 9.783072e+11 1 NaT NaN NaN 2 2001-01-03 9.784800e+14 9.784800e+11 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_dt_timestamp(df_pl) shape: (3, 3) ┌────────────┬─────────────────┬──────────────┐ │ date ┆ timestamp_us ┆ timestamp_ms │ @@ -5863,7 +6451,8 @@ def timestamp(self: Self, time_unit: Literal["ns", "us", "ms"] = "us") -> ExprT: │ null ┆ null ┆ null │ │ 2001-01-03 ┆ 978480000000000 ┆ 978480000000 │ └────────────┴─────────────────┴──────────────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_dt_timestamp(df_pa) pyarrow.Table date: date32[day] timestamp_us: int64 @@ -5900,27 +6489,33 @@ def keep(self: Self) -> ExprT: expression in a chain. Only one name operation per expression will work. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrame + >>> >>> data = {"foo": [1, 2], "BAR": [4, 5]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_name_keep(df_native: IntoFrame) -> list[str]: ... df = nw.from_native(df_native) - ... return df.select( - ... nw.col("foo").alias("alias_for_foo").name.keep() - ... ).to_native() + ... return df.select(nw.col("foo").alias("alias_for_foo").name.keep()).columns + + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_name_keep`: - We can then pass either pandas or Polars to `func`: + >>> agnostic_name_keep(df_pd) + ['foo'] + + >>> agnostic_name_keep(df_pl) + ['foo'] - >>> my_library_agnostic_function(df_pd).columns - Index(['foo'], dtype='object') - >>> my_library_agnostic_function(df_pl).columns + >>> agnostic_name_keep(df_pa) ['foo'] """ return self._expr.__class__( @@ -5942,26 +6537,34 @@ def map(self: Self, function: Callable[[str], str]) -> ExprT: expression in a chain. Only one name operation per expression will work. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrame + >>> >>> data = {"foo": [1, 2], "BAR": [4, 5]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: >>> renaming_func = lambda s: s[::-1] # reverse column name - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_name_map(df_native: IntoFrame) -> list[str]: ... df = nw.from_native(df_native) - ... return df.select(nw.col("foo", "BAR").name.map(renaming_func)).to_native() + ... return df.select(nw.col("foo", "BAR").name.map(renaming_func)).columns + + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_name_map`: - We can then pass either pandas or Polars to `func`: + >>> agnostic_name_map(df_pd) + ['oof', 'RAB'] + + >>> agnostic_name_map(df_pl) + ['oof', 'RAB'] - >>> my_library_agnostic_function(df_pd).columns - Index(['oof', 'RAB'], dtype='object') - >>> my_library_agnostic_function(df_pl).columns + >>> agnostic_name_map(df_pa) ['oof', 'RAB'] """ return self._expr.__class__( @@ -5983,26 +6586,33 @@ def prefix(self: Self, prefix: str) -> ExprT: expression in a chain. Only one name operation per expression will work. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrame + >>> >>> data = {"foo": [1, 2], "BAR": [4, 5]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def add_colname_prefix(df_native: IntoFrameT, prefix: str) -> IntoFrameT: + >>> def agnostic_name_prefix(df_native: IntoFrame, prefix: str) -> list[str]: ... df = nw.from_native(df_native) - ... return df.select(nw.col("foo", "BAR").name.prefix(prefix)).to_native() + ... return df.select(nw.col("foo", "BAR").name.prefix(prefix)).columns - We can then pass either pandas or Polars to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_name_prefix`: + + >>> agnostic_name_prefix(df_pd, "with_prefix_") + ['with_prefix_foo', 'with_prefix_BAR'] - >>> add_colname_prefix(df_pd, "with_prefix_").columns - Index(['with_prefix_foo', 'with_prefix_BAR'], dtype='object') + >>> agnostic_name_prefix(df_pl, "with_prefix_") + ['with_prefix_foo', 'with_prefix_BAR'] - >>> add_colname_prefix(df_pl, "with_prefix_").columns + >>> agnostic_name_prefix(df_pa, "with_prefix_") ['with_prefix_foo', 'with_prefix_BAR'] """ return self._expr.__class__( @@ -6024,25 +6634,33 @@ def suffix(self: Self, suffix: str) -> ExprT: expression in a chain. Only one name operation per expression will work. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrame + >>> >>> data = {"foo": [1, 2], "BAR": [4, 5]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def add_colname_suffix(df_native: IntoFrameT, suffix: str) -> IntoFrameT: + >>> def agnostic_name_suffix(df_native: IntoFrame, suffix: str) -> list[str]: ... df = nw.from_native(df_native) - ... return df.select(nw.col("foo", "BAR").name.suffix(suffix)).to_native() + ... return df.select(nw.col("foo", "BAR").name.suffix(suffix)).columns + + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_name_suffix`: - We can then pass either pandas or Polars to `func`: + >>> agnostic_name_suffix(df_pd, "_with_suffix") + ['foo_with_suffix', 'BAR_with_suffix'] + + >>> agnostic_name_suffix(df_pl, "_with_suffix") + ['foo_with_suffix', 'BAR_with_suffix'] - >>> add_colname_suffix(df_pd, "_with_suffix").columns - Index(['foo_with_suffix', 'BAR_with_suffix'], dtype='object') - >>> add_colname_suffix(df_pl, "_with_suffix").columns + >>> agnostic_name_suffix(df_pa, "_with_suffix") ['foo_with_suffix', 'BAR_with_suffix'] """ return self._expr.__class__( @@ -6061,25 +6679,33 @@ def to_lowercase(self: Self) -> ExprT: expression in a chain. Only one name operation per expression will work. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrame + >>> >>> data = {"foo": [1, 2], "BAR": [4, 5]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def to_lower(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_name_to_lowercase(df_native: IntoFrame) -> list[str]: ... df = nw.from_native(df_native) - ... return df.select(nw.col("foo", "BAR").name.to_lowercase()).to_native() + ... return df.select(nw.col("foo", "BAR").name.to_lowercase()).columns + + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_name_to_lowercase`: - We can then pass either pandas or Polars to `func`: + >>> agnostic_name_to_lowercase(df_pd) + ['foo', 'bar'] + + >>> agnostic_name_to_lowercase(df_pl) + ['foo', 'bar'] - >>> to_lower(df_pd).columns - Index(['foo', 'bar'], dtype='object') - >>> to_lower(df_pl).columns + >>> agnostic_name_to_lowercase(df_pa) ['foo', 'bar'] """ return self._expr.__class__( @@ -6098,24 +6724,33 @@ def to_uppercase(self: Self) -> ExprT: expression in a chain. Only one name operation per expression will work. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl + >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrame + >>> >>> data = {"foo": [1, 2], "BAR": [4, 5]} >>> df_pd = pd.DataFrame(data) >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def to_upper(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_name_to_uppercase(df_native: IntoFrame) -> list[str]: ... df = nw.from_native(df_native) - ... return df.select(nw.col("foo", "BAR").name.to_uppercase()).to_native() + ... return df.select(nw.col("foo", "BAR").name.to_uppercase()).columns + + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_name_to_uppercase`: + + >>> agnostic_name_to_uppercase(df_pd) + ['FOO', 'BAR'] + + >>> agnostic_name_to_uppercase(df_pl) + ['FOO', 'BAR'] - We can then pass either pandas or Polars to `func`: - >>> to_upper(df_pd).columns - Index(['FOO', 'BAR'], dtype='object') - >>> to_upper(df_pl).columns + >>> agnostic_name_to_uppercase(df_pa) ['FOO', 'BAR'] """ return self._expr.__class__( @@ -6136,11 +6771,12 @@ def len(self: Self) -> ExprT: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [[1, 2], [3, 4, None], None, []]} Let's define a dataframe-agnostic function: @@ -6202,23 +6838,27 @@ def col(*names: str | Iterable[str]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pl = pl.DataFrame({"a": [1, 2], "b": [3, 4]}) - >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [3, 4]}) - >>> df_pa = pa.table({"a": [1, 2], "b": [3, 4]}) + >>> + >>> data = {"a": [1, 2], "b": [3, 4]} + >>> df_pl = pl.DataFrame(data) + >>> df_pd = pd.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_col(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a") * nw.col("b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_col`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_col(df_pd) a 0 3 1 8 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_col(df_pl) shape: (2, 1) ┌─────┐ │ a │ @@ -6228,7 +6868,8 @@ def col(*names: str | Iterable[str]) -> Expr: │ 3 │ │ 8 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_col(df_pa) pyarrow.Table a: int64 ---- @@ -6260,6 +6901,7 @@ def nth(*indices: int | Sequence[int]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2], "b": [3, 4]} >>> df_pl = pl.DataFrame(data) >>> df_pd = pd.DataFrame(data) @@ -6267,17 +6909,18 @@ def nth(*indices: int | Sequence[int]) -> Expr: We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_nth(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.nth(0) * 2).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_nth`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_nth(df_pd) a 0 2 1 4 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_nth(df_pl) shape: (2, 1) ┌─────┐ │ a │ @@ -6287,7 +6930,8 @@ def nth(*indices: int | Sequence[int]) -> Expr: │ 2 │ │ 4 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_nth(df_pa) pyarrow.Table a: int64 ---- @@ -6313,24 +6957,28 @@ def all_() -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}) - >>> df_pl = pl.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}) - >>> df_pa = pa.table({"a": [1, 2, 3], "b": [4, 5, 6]}) + >>> + >>> data = {"a": [1, 2, 3], "b": [4, 5, 6]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_all(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.all() * 2).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_all`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_all(df_pd) a b 0 2 8 1 4 10 2 6 12 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_all(df_pl) shape: (3, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -6341,7 +6989,8 @@ def all_() -> Expr: │ 4 ┆ 10 │ │ 6 ┆ 12 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_all(df_pa) pyarrow.Table a: int64 b: int64 @@ -6365,22 +7014,25 @@ def len_() -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pl = pl.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pa = pa.table({"a": [1, 2], "b": [5, 10]}) + >>> + >>> data = {"a": [1, 2], "b": [5, 10]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_len(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.len()).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_len`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_len(df_pd) len 0 2 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_len(df_pl) shape: (1, 1) ┌─────┐ │ len │ @@ -6389,7 +7041,7 @@ def len_() -> Expr: ╞═════╡ │ 2 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_len(df_pa) pyarrow.Table len: int64 ---- @@ -6420,22 +7072,26 @@ def sum(*columns: str) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pl = pl.DataFrame({"a": [1, 2]}) - >>> df_pd = pd.DataFrame({"a": [1, 2]}) - >>> df_pa = pa.table({"a": [1, 2]}) + >>> + >>> data = {"a": [1, 2]} + >>> df_pl = pl.DataFrame(data) + >>> df_pd = pd.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_sum(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.sum("a")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_sum`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_sum(df_pd) a 0 3 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_sum(df_pl) shape: (1, 1) ┌─────┐ │ a │ @@ -6444,7 +7100,8 @@ def sum(*columns: str) -> Expr: ╞═════╡ │ 3 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_sum(df_pa) pyarrow.Table a: int64 ---- @@ -6471,22 +7128,26 @@ def mean(*columns: str) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pl = pl.DataFrame({"a": [1, 8, 3]}) - >>> df_pd = pd.DataFrame({"a": [1, 8, 3]}) - >>> df_pa = pa.table({"a": [1, 8, 3]}) + >>> + >>> data = {"a": [1, 8, 3]} + >>> df_pl = pl.DataFrame(data) + >>> df_pd = pd.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_mean(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.mean("a")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_mean`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_mean(df_pd) a 0 4.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_mean(df_pl) shape: (1, 1) ┌─────┐ │ a │ @@ -6495,7 +7156,8 @@ def mean(*columns: str) -> Expr: ╞═════╡ │ 4.0 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_mean(df_pa) pyarrow.Table a: double ---- @@ -6509,7 +7171,8 @@ def median(*columns: str) -> Expr: Notes: - Syntactic sugar for ``nw.col(columns).median()`` - - Results might slightly differ across backends due to differences in the underlying algorithms used to compute the median. + - Results might slightly differ across backends due to differences in the + underlying algorithms used to compute the median. Arguments: columns: Name(s) of the columns to use in the aggregation function @@ -6523,22 +7186,26 @@ def median(*columns: str) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [4, 5, 2]}) - >>> df_pl = pl.DataFrame({"a": [4, 5, 2]}) - >>> df_pa = pa.table({"a": [4, 5, 2]}) + >>> + >>> data = {"a": [4, 5, 2]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_median(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.median("a")).to_native() - We can then pass any supported library such as pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_median`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_median(df_pd) a 0 4.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_median(df_pl) shape: (1, 1) ┌─────┐ │ a │ @@ -6547,7 +7214,8 @@ def median(*columns: str) -> Expr: ╞═════╡ │ 4.0 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_median(df_pa) pyarrow.Table a: double ---- @@ -6574,22 +7242,26 @@ def min(*columns: str) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pl = pl.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pa = pa.table({"a": [1, 2], "b": [5, 10]}) + >>> + >>> data = {"a": [1, 2], "b": [5, 10]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_min(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.min("b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_min`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_min(df_pd) b 0 5 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_min(df_pl) shape: (1, 1) ┌─────┐ │ b │ @@ -6598,7 +7270,8 @@ def min(*columns: str) -> Expr: ╞═════╡ │ 5 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_min(df_pa) pyarrow.Table b: int64 ---- @@ -6625,22 +7298,26 @@ def max(*columns: str) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pl = pl.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pa = pa.table({"a": [1, 2], "b": [5, 10]}) + >>> + >>> data = {"a": [1, 2], "b": [5, 10]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_max(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.max("a")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_max`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_max(df_pd) a 0 2 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_max(df_pl) shape: (1, 1) ┌─────┐ │ a │ @@ -6649,7 +7326,8 @@ def max(*columns: str) -> Expr: ╞═════╡ │ 2 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_max(df_pa) pyarrow.Table a: int64 ---- @@ -6677,6 +7355,7 @@ def sum_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3], "b": [5, 10, None]} >>> df_pl = pl.DataFrame(data) >>> df_pd = pd.DataFrame(data) @@ -6684,18 +7363,19 @@ def sum_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_sum_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.sum_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_sum_horizontal`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_sum_horizontal(df_pd) a 0 6.0 1 12.0 2 3.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_sum_horizontal(df_pl) shape: (3, 1) ┌─────┐ │ a │ @@ -6706,7 +7386,8 @@ def sum_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ 12 │ │ 3 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_sum_horizontal(df_pa) pyarrow.Table a: int64 ---- @@ -6736,11 +7417,12 @@ def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [1, 8, 3], ... "b": [4, 5, None], @@ -6750,18 +7432,20 @@ def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function that computes the horizontal min of "a" and "b" columns: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_min_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.min_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_min_horizontal`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_min_horizontal(pd.DataFrame(data)) a 0 1.0 1 5.0 2 3.0 - >>> my_library_agnostic_function(pl.DataFrame(data)) + + >>> agnostic_min_horizontal(pl.DataFrame(data)) shape: (3, 1) ┌─────┐ │ a │ @@ -6772,7 +7456,8 @@ def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ 5 │ │ 3 │ └─────┘ - >>> my_library_agnostic_function(pa.table(data)) + + >>> agnostic_min_horizontal(pa.table(data)) pyarrow.Table a: int64 ---- @@ -6802,11 +7487,12 @@ def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [1, 8, 3], ... "b": [4, 5, None], @@ -6816,18 +7502,20 @@ def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function that computes the horizontal max of "a" and "b" columns: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_max_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.max_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_max_horizontal`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_max_horizontal(pd.DataFrame(data)) a 0 4.0 1 8.0 2 3.0 - >>> my_library_agnostic_function(pl.DataFrame(data)) + + >>> agnostic_max_horizontal(pl.DataFrame(data)) shape: (3, 1) ┌─────┐ │ a │ @@ -6838,7 +7526,8 @@ def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ 8 │ │ 3 │ └─────┘ - >>> my_library_agnostic_function(pa.table(data)) + + >>> agnostic_max_horizontal(pa.table(data)) pyarrow.Table a: int64 ---- @@ -6892,9 +7581,9 @@ def when(*predicates: IntoExpr | Iterable[IntoExpr]) -> When: If not appended, and none of the conditions are `True`, `None` will be returned. Arguments: - predicates: Condition(s) that must be met in order to apply the subsequent statement. - Accepts one or more boolean expressions, which are implicitly combined with `&`. - String input is parsed as a column name. + predicates: Condition(s) that must be met in order to apply the subsequent + statement. Accepts one or more boolean expressions, which are implicitly + combined with `&`. String input is parsed as a column name. Returns: A "when" object, which `.then` can be called on. @@ -6905,26 +7594,30 @@ def when(*predicates: IntoExpr | Iterable[IntoExpr]) -> When: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pl = pl.DataFrame({"a": [1, 2, 3], "b": [5, 10, 15]}) - >>> df_pd = pd.DataFrame({"a": [1, 2, 3], "b": [5, 10, 15]}) - >>> df_pa = pa.table({"a": [1, 2, 3], "b": [5, 10, 15]}) + >>> + >>> data = {"a": [1, 2, 3], "b": [5, 10, 15]} + >>> df_pl = pl.DataFrame(data) + >>> df_pd = pd.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_when_then_otherwise(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... nw.when(nw.col("a") < 3).then(5).otherwise(6).alias("a_when") ... ).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_when_then_otherwise`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_when_then_otherwise(df_pd) a b a_when 0 1 5 5 1 2 10 5 2 3 15 6 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_when_then_otherwise(df_pl) shape: (3, 3) ┌─────┬─────┬────────┐ │ a ┆ b ┆ a_when │ @@ -6935,7 +7628,8 @@ def when(*predicates: IntoExpr | Iterable[IntoExpr]) -> When: │ 2 ┆ 10 ┆ 5 │ │ 3 ┆ 15 ┆ 6 │ └─────┴─────┴────────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_when_then_otherwise(df_pa) pyarrow.Table a: int64 b: int64 @@ -6952,7 +7646,8 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: r"""Compute the bitwise AND horizontally across columns. Arguments: - exprs: Name(s) of the columns to use in the aggregation function. Accepts expression input. + exprs: Name(s) of the columns to use in the aggregation function. Accepts + expression input. Returns: A new expression. @@ -6963,6 +7658,7 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [False, False, True, True, False, None], ... "b": [False, True, True, None, None, None], @@ -6973,13 +7669,14 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_all_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select("a", "b", all=nw.all_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_all_horizontal`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_all_horizontal(df_pd) a b all 0 False False False 1 False True False @@ -6988,7 +7685,7 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: 4 False False 5 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_all_horizontal(df_pl) shape: (6, 3) ┌───────┬───────┬───────┐ │ a ┆ b ┆ all │ @@ -7003,7 +7700,7 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ null ┆ null ┆ null │ └───────┴───────┴───────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_all_horizontal(df_pa) pyarrow.Table a: bool b: bool @@ -7028,7 +7725,8 @@ def lit(value: Any, dtype: DType | type[DType] | None = None) -> Expr: Arguments: value: The value to use as literal. - dtype: The data type of the literal value. If not provided, the data type will be inferred. + dtype: The data type of the literal value. If not provided, the data type will + be inferred. Returns: A new expression. @@ -7039,23 +7737,27 @@ def lit(value: Any, dtype: DType | type[DType] | None = None) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pl = pl.DataFrame({"a": [1, 2]}) - >>> df_pd = pd.DataFrame({"a": [1, 2]}) - >>> df_pa = pa.table({"a": [1, 2]}) + >>> + >>> data = {"a": [1, 2]} + >>> df_pl = pl.DataFrame(data) + >>> df_pd = pd.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_lit(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns(nw.lit(3)).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_lit`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_lit(df_pd) a literal 0 1 3 1 2 3 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_lit(df_pl) shape: (2, 2) ┌─────┬─────────┐ │ a ┆ literal │ @@ -7065,7 +7767,8 @@ def lit(value: Any, dtype: DType | type[DType] | None = None) -> Expr: │ 1 ┆ 3 │ │ 2 ┆ 3 │ └─────┴─────────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_lit(df_pa) pyarrow.Table a: int64 literal: int64 @@ -7091,7 +7794,8 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: r"""Compute the bitwise OR horizontally across columns. Arguments: - exprs: Name(s) of the columns to use in the aggregation function. Accepts expression input. + exprs: Name(s) of the columns to use in the aggregation function. Accepts + expression input. Returns: A new expression. @@ -7102,6 +7806,7 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [False, False, True, True, False, None], ... "b": [False, True, True, None, None, None], @@ -7112,13 +7817,14 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_any_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select("a", "b", any=nw.any_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_any_horizontal`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_any_horizontal(df_pd) a b any 0 False False False 1 False True True @@ -7127,7 +7833,7 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: 4 False 5 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_any_horizontal(df_pl) shape: (6, 3) ┌───────┬───────┬───────┐ │ a ┆ b ┆ any │ @@ -7142,7 +7848,7 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ null ┆ null ┆ null │ └───────┴───────┴───────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_any_horizontal(df_pa) pyarrow.Table a: bool b: bool @@ -7178,6 +7884,7 @@ def mean_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [1, 8, 3], ... "b": [4, 5, None], @@ -7190,19 +7897,20 @@ def mean_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function that computes the horizontal mean of "a" and "b" columns: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_mean_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.mean_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_mean_horizontal`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_mean_horizontal(df_pd) a 0 2.5 1 6.5 2 3.0 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_mean_horizontal(df_pl) shape: (3, 1) ┌─────┐ │ a │ @@ -7214,7 +7922,7 @@ def mean_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ 3.0 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_mean_horizontal(df_pa) pyarrow.Table a: double ---- @@ -7253,11 +7961,12 @@ def concat_str( A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [1, 2, 3], ... "b": ["dogs", "cats", None], @@ -7267,7 +7976,7 @@ def concat_str( We define a dataframe-agnostic function that computes the horizontal string concatenation of different columns - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_concat_str(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.concat_str( @@ -7280,15 +7989,16 @@ def concat_str( ... ).alias("full_sentence") ... ).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow + to `agnostic_concat_str`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_concat_str(pd.DataFrame(data)) full_sentence 0 2 dogs play 1 4 cats swim 2 None - >>> my_library_agnostic_function(pl.DataFrame(data)) + >>> agnostic_concat_str(pl.DataFrame(data)) shape: (3, 1) ┌───────────────┐ │ full_sentence │ @@ -7300,7 +8010,7 @@ def concat_str( │ null │ └───────────────┘ - >>> my_library_agnostic_function(pa.table(data)) + >>> agnostic_concat_str(pa.table(data)) pyarrow.Table full_sentence: string ---- diff --git a/narwhals/stable/v1/__init__.py b/narwhals/stable/v1/__init__.py index 5ffc475e5..cb5d2006c 100644 --- a/narwhals/stable/v1/__init__.py +++ b/narwhals/stable/v1/__init__.py @@ -2353,24 +2353,28 @@ def all() -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}) - >>> df_pl = pl.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}) - >>> df_pa = pa.table({"a": [1, 2, 3], "b": [4, 5, 6]}) + >>> + >>> data = {"a": [1, 2, 3], "b": [4, 5, 6]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_all(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.all() * 2).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_all`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_all(df_pd) a b 0 2 8 1 4 10 2 6 12 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_all(df_pl) shape: (3, 2) ┌─────┬─────┐ │ a ┆ b │ @@ -2381,7 +2385,8 @@ def all() -> Expr: │ 4 ┆ 10 │ │ 6 ┆ 12 │ └─────┴─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_all(df_pa) pyarrow.Table a: int64 b: int64 @@ -2407,23 +2412,27 @@ def col(*names: str | Iterable[str]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pl = pl.DataFrame({"a": [1, 2], "b": [3, 4]}) - >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [3, 4]}) - >>> df_pa = pa.table({"a": [1, 2], "b": [3, 4]}) + >>> + >>> data = {"a": [1, 2], "b": [3, 4]} + >>> df_pl = pl.DataFrame(data) + >>> df_pd = pd.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_col(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.col("a") * nw.col("b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_col`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_col(df_pd) a 0 3 1 8 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_col(df_pl) shape: (2, 1) ┌─────┐ │ a │ @@ -2433,7 +2442,8 @@ def col(*names: str | Iterable[str]) -> Expr: │ 3 │ │ 8 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_col(df_pa) pyarrow.Table a: int64 ---- @@ -2461,6 +2471,7 @@ def nth(*indices: int | Sequence[int]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2], "b": [3, 4]} >>> df_pl = pl.DataFrame(data) >>> df_pd = pd.DataFrame(data) @@ -2468,17 +2479,18 @@ def nth(*indices: int | Sequence[int]) -> Expr: We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_nth(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.nth(0) * 2).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_nth`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_nth(df_pd) a 0 2 1 4 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_nth(df_pl) shape: (2, 1) ┌─────┐ │ a │ @@ -2488,7 +2500,8 @@ def nth(*indices: int | Sequence[int]) -> Expr: │ 2 │ │ 4 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_nth(df_pa) pyarrow.Table a: int64 ---- @@ -2509,22 +2522,25 @@ def len() -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pl = pl.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pa = pa.table({"a": [1, 2], "b": [5, 10]}) + >>> + >>> data = {"a": [1, 2], "b": [5, 10]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_len(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.len()).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_len`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_len(df_pd) len 0 2 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_len(df_pl) shape: (1, 1) ┌─────┐ │ len │ @@ -2533,7 +2549,7 @@ def len() -> Expr: ╞═════╡ │ 2 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_len(df_pa) pyarrow.Table len: int64 ---- @@ -2547,7 +2563,8 @@ def lit(value: Any, dtype: DType | type[DType] | None = None) -> Expr: Arguments: value: The value to use as literal. - dtype: The data type of the literal value. If not provided, the data type will be inferred. + dtype: The data type of the literal value. If not provided, the data type will + be inferred. Returns: A new expression. @@ -2558,23 +2575,27 @@ def lit(value: Any, dtype: DType | type[DType] | None = None) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pl = pl.DataFrame({"a": [1, 2]}) - >>> df_pd = pd.DataFrame({"a": [1, 2]}) - >>> df_pa = pa.table({"a": [1, 2]}) + >>> + >>> data = {"a": [1, 2]} + >>> df_pl = pl.DataFrame(data) + >>> df_pd = pd.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_lit(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns(nw.lit(3)).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_lit`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_lit(df_pd) a literal 0 1 3 1 2 3 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_lit(df_pl) shape: (2, 2) ┌─────┬─────────┐ │ a ┆ literal │ @@ -2584,7 +2605,8 @@ def lit(value: Any, dtype: DType | type[DType] | None = None) -> Expr: │ 1 ┆ 3 │ │ 2 ┆ 3 │ └─────┴─────────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_lit(df_pa) pyarrow.Table a: int64 literal: int64 @@ -2613,22 +2635,26 @@ def min(*columns: str) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pl = pl.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pa = pa.table({"a": [1, 2], "b": [5, 10]}) + >>> + >>> data = {"a": [1, 2], "b": [5, 10]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_min(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.min("b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_min`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_min(df_pd) b 0 5 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_min(df_pl) shape: (1, 1) ┌─────┐ │ b │ @@ -2637,7 +2663,8 @@ def min(*columns: str) -> Expr: ╞═════╡ │ 5 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_min(df_pa) pyarrow.Table b: int64 ---- @@ -2664,22 +2691,26 @@ def max(*columns: str) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pl = pl.DataFrame({"a": [1, 2], "b": [5, 10]}) - >>> df_pa = pa.table({"a": [1, 2], "b": [5, 10]}) + >>> + >>> data = {"a": [1, 2], "b": [5, 10]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_max(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.max("a")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_max`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_max(df_pd) a 0 2 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_max(df_pl) shape: (1, 1) ┌─────┐ │ a │ @@ -2688,7 +2719,8 @@ def max(*columns: str) -> Expr: ╞═════╡ │ 2 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_max(df_pa) pyarrow.Table a: int64 ---- @@ -2715,22 +2747,26 @@ def mean(*columns: str) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pl = pl.DataFrame({"a": [1, 8, 3]}) - >>> df_pd = pd.DataFrame({"a": [1, 8, 3]}) - >>> df_pa = pa.table({"a": [1, 8, 3]}) + >>> + >>> data = {"a": [1, 8, 3]} + >>> df_pl = pl.DataFrame(data) + >>> df_pd = pd.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_mean(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.mean("a")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_mean`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_mean(df_pd) a 0 4.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_mean(df_pl) shape: (1, 1) ┌─────┐ │ a │ @@ -2739,7 +2775,8 @@ def mean(*columns: str) -> Expr: ╞═════╡ │ 4.0 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_mean(df_pa) pyarrow.Table a: double ---- @@ -2753,7 +2790,8 @@ def median(*columns: str) -> Expr: Notes: - Syntactic sugar for ``nw.col(columns).median()`` - - Results might slightly differ across backends due to differences in the underlying algorithms used to compute the median. + - Results might slightly differ across backends due to differences in the + underlying algorithms used to compute the median. Arguments: columns: Name(s) of the columns to use in the aggregation function @@ -2767,22 +2805,26 @@ def median(*columns: str) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pd = pd.DataFrame({"a": [4, 5, 2]}) - >>> df_pl = pl.DataFrame({"a": [4, 5, 2]}) - >>> df_pa = pa.table({"a": [4, 5, 2]}) + >>> + >>> data = {"a": [4, 5, 2]} + >>> df_pd = pd.DataFrame(data) + >>> df_pl = pl.DataFrame(data) + >>> df_pa = pa.table(data) Let's define a dataframe agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_median(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.median("a")).to_native() - We can then pass any supported library such as pandas, Polars, or PyArrow to `func`: + We can then pass any supported library such as pandas, Polars, or + PyArrow to `agnostic_median`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_median(df_pd) a 0 4.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_median(df_pl) shape: (1, 1) ┌─────┐ │ a │ @@ -2791,7 +2833,8 @@ def median(*columns: str) -> Expr: ╞═════╡ │ 4.0 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_median(df_pa) pyarrow.Table a: double ---- @@ -2818,22 +2861,26 @@ def sum(*columns: str) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pl = pl.DataFrame({"a": [1, 2]}) - >>> df_pd = pd.DataFrame({"a": [1, 2]}) - >>> df_pa = pa.table({"a": [1, 2]}) + >>> + >>> data = {"a": [1, 2]} + >>> df_pl = pl.DataFrame(data) + >>> df_pd = pd.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_sum(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.sum("a")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_sum`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_sum(df_pd) a 0 3 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_sum(df_pl) shape: (1, 1) ┌─────┐ │ a │ @@ -2842,7 +2889,8 @@ def sum(*columns: str) -> Expr: ╞═════╡ │ 3 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_sum(df_pa) pyarrow.Table a: int64 ---- @@ -2870,6 +2918,7 @@ def sum_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = {"a": [1, 2, 3], "b": [5, 10, None]} >>> df_pl = pl.DataFrame(data) >>> df_pd = pd.DataFrame(data) @@ -2877,18 +2926,19 @@ def sum_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_sum_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.sum_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to `agnostic_sum_horizontal`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_sum_horizontal(df_pd) a 0 6.0 1 12.0 2 3.0 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_sum_horizontal(df_pl) shape: (3, 1) ┌─────┐ │ a │ @@ -2899,7 +2949,8 @@ def sum_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ 12 │ │ 3 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_sum_horizontal(df_pa) pyarrow.Table a: int64 ---- @@ -2912,7 +2963,8 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: r"""Compute the bitwise AND horizontally across columns. Arguments: - exprs: Name(s) of the columns to use in the aggregation function. Accepts expression input. + exprs: Name(s) of the columns to use in the aggregation function. Accepts + expression input. Returns: A new expression. @@ -2923,6 +2975,7 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [False, False, True, True, False, None], ... "b": [False, True, True, None, None, None], @@ -2933,13 +2986,14 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_all_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select("a", "b", all=nw.all_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_all_horizontal`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_all_horizontal(df_pd) a b all 0 False False False 1 False True False @@ -2948,7 +3002,7 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: 4 False False 5 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_all_horizontal(df_pl) shape: (6, 3) ┌───────┬───────┬───────┐ │ a ┆ b ┆ all │ @@ -2963,7 +3017,7 @@ def all_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ null ┆ null ┆ null │ └───────┴───────┴───────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_all_horizontal(df_pa) pyarrow.Table a: bool b: bool @@ -2980,7 +3034,8 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: r"""Compute the bitwise OR horizontally across columns. Arguments: - exprs: Name(s) of the columns to use in the aggregation function. Accepts expression input. + exprs: Name(s) of the columns to use in the aggregation function. Accepts + expression input. Returns: A new expression. @@ -2991,6 +3046,7 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [False, False, True, True, False, None], ... "b": [False, True, True, None, None, None], @@ -3001,13 +3057,14 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_any_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select("a", "b", any=nw.any_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_any_horizontal`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_any_horizontal(df_pd) a b any 0 False False False 1 False True True @@ -3016,7 +3073,7 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: 4 False 5 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_any_horizontal(df_pl) shape: (6, 3) ┌───────┬───────┬───────┐ │ a ┆ b ┆ any │ @@ -3031,7 +3088,7 @@ def any_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ null ┆ null ┆ null │ └───────┴───────┴───────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_any_horizontal(df_pa) pyarrow.Table a: bool b: bool @@ -3060,6 +3117,7 @@ def mean_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [1, 8, 3], ... "b": [4, 5, None], @@ -3072,19 +3130,20 @@ def mean_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function that computes the horizontal mean of "a" and "b" columns: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_mean_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.mean_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_mean_horizontal`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_mean_horizontal(df_pd) a 0 2.5 1 6.5 2 3.0 - >>> my_library_agnostic_function(df_pl) + >>> agnostic_mean_horizontal(df_pl) shape: (3, 1) ┌─────┐ │ a │ @@ -3096,7 +3155,7 @@ def mean_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ 3.0 │ └─────┘ - >>> my_library_agnostic_function(df_pa) + >>> agnostic_mean_horizontal(df_pa) pyarrow.Table a: double ---- @@ -3119,11 +3178,12 @@ def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [1, 8, 3], ... "b": [4, 5, None], @@ -3133,18 +3193,20 @@ def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function that computes the horizontal min of "a" and "b" columns: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_min_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.min_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_min_horizontal`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_min_horizontal(pd.DataFrame(data)) a 0 1.0 1 5.0 2 3.0 - >>> my_library_agnostic_function(pl.DataFrame(data)) + + >>> agnostic_min_horizontal(pl.DataFrame(data)) shape: (3, 1) ┌─────┐ │ a │ @@ -3155,7 +3217,8 @@ def min_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ 5 │ │ 3 │ └─────┘ - >>> my_library_agnostic_function(pa.table(data)) + + >>> agnostic_min_horizontal(pa.table(data)) pyarrow.Table a: int64 ---- @@ -3178,11 +3241,12 @@ def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [1, 8, 3], ... "b": [4, 5, None], @@ -3192,18 +3256,20 @@ def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: We define a dataframe-agnostic function that computes the horizontal max of "a" and "b" columns: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_max_horizontal(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select(nw.max_horizontal("a", "b")).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_max_horizontal`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_max_horizontal(pd.DataFrame(data)) a 0 4.0 1 8.0 2 3.0 - >>> my_library_agnostic_function(pl.DataFrame(data)) + + >>> agnostic_max_horizontal(pl.DataFrame(data)) shape: (3, 1) ┌─────┐ │ a │ @@ -3214,7 +3280,8 @@ def max_horizontal(*exprs: IntoExpr | Iterable[IntoExpr]) -> Expr: │ 8 │ │ 3 │ └─────┘ - >>> my_library_agnostic_function(pa.table(data)) + + >>> agnostic_max_horizontal(pa.table(data)) pyarrow.Table a: int64 ---- @@ -3405,11 +3472,12 @@ def concat_str( A new expression. Examples: - >>> import narwhals as nw - >>> from narwhals.typing import IntoFrameT >>> import pandas as pd >>> import polars as pl >>> import pyarrow as pa + >>> import narwhals as nw + >>> from narwhals.typing import IntoFrameT + >>> >>> data = { ... "a": [1, 2, 3], ... "b": ["dogs", "cats", None], @@ -3419,7 +3487,7 @@ def concat_str( We define a dataframe-agnostic function that computes the horizontal string concatenation of different columns - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_concat_str(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.select( ... nw.concat_str( @@ -3432,15 +3500,16 @@ def concat_str( ... ).alias("full_sentence") ... ).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow + to `agnostic_concat_str`: - >>> my_library_agnostic_function(pd.DataFrame(data)) + >>> agnostic_concat_str(pd.DataFrame(data)) full_sentence 0 2 dogs play 1 4 cats swim 2 None - >>> my_library_agnostic_function(pl.DataFrame(data)) + >>> agnostic_concat_str(pl.DataFrame(data)) shape: (3, 1) ┌───────────────┐ │ full_sentence │ @@ -3452,7 +3521,7 @@ def concat_str( │ null │ └───────────────┘ - >>> my_library_agnostic_function(pa.table(data)) + >>> agnostic_concat_str(pa.table(data)) pyarrow.Table full_sentence: string ---- @@ -3495,9 +3564,9 @@ def when(*predicates: IntoExpr | Iterable[IntoExpr]) -> When: If not appended, and none of the conditions are `True`, `None` will be returned. Arguments: - predicates: Condition(s) that must be met in order to apply the subsequent statement. - Accepts one or more boolean expressions, which are implicitly combined with `&`. - String input is parsed as a column name. + predicates: Condition(s) that must be met in order to apply the subsequent + statement. Accepts one or more boolean expressions, which are implicitly + combined with `&`. String input is parsed as a column name. Returns: A "when" object, which `.then` can be called on. @@ -3508,26 +3577,30 @@ def when(*predicates: IntoExpr | Iterable[IntoExpr]) -> When: >>> import pyarrow as pa >>> import narwhals as nw >>> from narwhals.typing import IntoFrameT - >>> df_pl = pl.DataFrame({"a": [1, 2, 3], "b": [5, 10, 15]}) - >>> df_pd = pd.DataFrame({"a": [1, 2, 3], "b": [5, 10, 15]}) - >>> df_pa = pa.table({"a": [1, 2, 3], "b": [5, 10, 15]}) + >>> + >>> data = {"a": [1, 2, 3], "b": [5, 10, 15]} + >>> df_pl = pl.DataFrame(data) + >>> df_pd = pd.DataFrame(data) + >>> df_pa = pa.table(data) We define a dataframe-agnostic function: - >>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT: + >>> def agnostic_when_then_otherwise(df_native: IntoFrameT) -> IntoFrameT: ... df = nw.from_native(df_native) ... return df.with_columns( ... nw.when(nw.col("a") < 3).then(5).otherwise(6).alias("a_when") ... ).to_native() - We can pass any supported library such as Pandas, Polars, or PyArrow to `func`: + We can pass any supported library such as Pandas, Polars, or PyArrow to + `agnostic_when_then_otherwise`: - >>> my_library_agnostic_function(df_pd) + >>> agnostic_when_then_otherwise(df_pd) a b a_when 0 1 5 5 1 2 10 5 2 3 15 6 - >>> my_library_agnostic_function(df_pl) + + >>> agnostic_when_then_otherwise(df_pl) shape: (3, 3) ┌─────┬─────┬────────┐ │ a ┆ b ┆ a_when │ @@ -3538,7 +3611,8 @@ def when(*predicates: IntoExpr | Iterable[IntoExpr]) -> When: │ 2 ┆ 10 ┆ 5 │ │ 3 ┆ 15 ┆ 6 │ └─────┴─────┴────────┘ - >>> my_library_agnostic_function(df_pa) + + >>> agnostic_when_then_otherwise(df_pa) pyarrow.Table a: int64 b: int64