From 4c6a7f9030bdc8a867ae0b685ad15ae380b649ce Mon Sep 17 00:00:00 2001 From: ugohuche Date: Sun, 5 May 2024 20:13:30 +0100 Subject: [PATCH 1/2] Added docstring for Expr.is_null --- narwhals/expression.py | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/narwhals/expression.py b/narwhals/expression.py index 214813315..76145f2bb 100644 --- a/narwhals/expression.py +++ b/narwhals/expression.py @@ -410,6 +410,56 @@ def filter(self, other: Any) -> Expr: ) def is_null(self) -> Expr: + """ + Returns a boolean Series indicating which values are null. + + Examples: + >>> import pandas as pd + >>> import polars as pl + >>> import narwhals as nw + >>> 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, float("nan"), 3.0, 5.0] + ... } + ... ) + + Let's define a dataframe-agnostic function: + + >>> def func(df_any): + ... df = nw.from_native(df_any) + ... df = df.with_columns(nw.all().is_null()) # nan != null for polars + ... return nw.to_native(df) + + We can then pass either pandas or Polars to `func`: + + >>> func(df_pd) + a b + 0 False False + 1 False False + 2 True True + 3 False False + 4 False False + >>> func(df_pl) + shape: (5, 2) + ┌───────┬───────┐ + │ a ┆ b │ + │ --- ┆ --- │ + │ bool ┆ bool │ + ╞═══════╪═══════╡ + │ false ┆ false │ + │ false ┆ false │ + │ true ┆ false │ + │ false ┆ false │ + │ false ┆ false │ + └───────┴───────┘ + """ return self.__class__(lambda plx: self._call(plx).is_null()) # --- partial reduction --- From c2d8320ce45270533cbaa99d6385594657c364e4 Mon Sep 17 00:00:00 2001 From: ugohuche Date: Mon, 6 May 2024 13:44:52 +0100 Subject: [PATCH 2/2] Modified docstring example for Expr.is_null --- narwhals/expression.py | 44 +++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/narwhals/expression.py b/narwhals/expression.py index 76145f2bb..4dd5d6a50 100644 --- a/narwhals/expression.py +++ b/narwhals/expression.py @@ -434,31 +434,35 @@ def is_null(self) -> Expr: >>> def func(df_any): ... df = nw.from_native(df_any) - ... df = df.with_columns(nw.all().is_null()) # nan != null for polars + ... df = df.with_columns( + ... a_is_null = nw.col('a').is_null(), + ... b_is_null = nw.col('b').is_null() + ... ) ... return nw.to_native(df) We can then pass either pandas or Polars to `func`: >>> func(df_pd) - a b - 0 False False - 1 False False - 2 True True - 3 False False - 4 False False - >>> func(df_pl) - shape: (5, 2) - ┌───────┬───────┐ - │ a ┆ b │ - │ --- ┆ --- │ - │ bool ┆ bool │ - ╞═══════╪═══════╡ - │ false ┆ false │ - │ false ┆ false │ - │ true ┆ false │ - │ false ┆ false │ - │ false ┆ false │ - └───────┴───────┘ + a b a_is_null b_is_null + 0 2.0 2.0 False False + 1 4.0 4.0 False False + 2 NaN NaN True True + 3 3.0 3.0 False False + 4 5.0 5.0 False False + + >>> func(df_pl) # nan != null for polars + shape: (5, 4) + ┌──────┬─────┬───────────┬───────────┐ + │ a ┆ b ┆ a_is_null ┆ b_is_null │ + │ --- ┆ --- ┆ --- ┆ --- │ + │ i64 ┆ f64 ┆ bool ┆ bool │ + ╞══════╪═════╪═══════════╪═══════════╡ + │ 2 ┆ 2.0 ┆ false ┆ false │ + │ 4 ┆ 4.0 ┆ false ┆ false │ + │ null ┆ NaN ┆ true ┆ false │ + │ 3 ┆ 3.0 ┆ false ┆ false │ + │ 5 ┆ 5.0 ┆ false ┆ false │ + └──────┴─────┴───────────┴───────────┘ """ return self.__class__(lambda plx: self._call(plx).is_null())