From 82902866d4b416ed6e2232d55477eef07500c7b3 Mon Sep 17 00:00:00 2001 From: Franco Masotti Date: Wed, 27 Mar 2024 13:57:56 +0100 Subject: [PATCH 1/8] Add first docstring - Add docstring for narwhals.dataframe.DataFrame --- .gitignore | 5 +++++ narwhals/dataframe.py | 45 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/.gitignore b/.gitignore index 9a2584d6f..01d41e44c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,8 @@ todo.md .coverage site/ .coverage.* + +Makefile +requirements-freeze.txt +.requirements-freeze-hashes.txt +.project.mk diff --git a/narwhals/dataframe.py b/narwhals/dataframe.py index 1b3f9f0d0..e0b25cb25 100644 --- a/narwhals/dataframe.py +++ b/narwhals/dataframe.py @@ -221,6 +221,51 @@ def columns(self) -> list[str]: def with_columns( self, *exprs: IntoExpr | Iterable[IntoExpr], **named_exprs: IntoExpr ) -> Self: + r""" + Add columns to this DataFrame. + + Added columns will replace existing columns with the same name. + + Arguments: + *exprs: Column(s) to add, specified as positional arguments. + Accepts expression input. Strings are parsed as column names, other + non-expression inputs are parsed as literals. + + **named_exprs: Additional columns to add, specified as keyword arguments. + The columns will be renamed to the keyword used. + + Returns: + DataFrame: A new DataFrame with the columns added. + + Note: + Creating a new DataFrame using this method does not create a new copy of + existing data. + + Examples: Pass an expression to add it as a new column. + ```python + >>> df_pl = pl.DataFrame( + ... { + ... "a": [1, 2, 3, 4], + ... "b": [0.5, 4, 10, 13], + ... "c": [True, True, False, True], + ... } + ... ) + >>> df = nw.DataFrame(df_pl) + >>> df = df.with_columns((pl.col("a") ** 2).alias("a^2")) + >>> nw.to_native(df) + shape: (4, 4) + ┌─────┬──────┬───────┬──────┐ + │ a ┆ b ┆ c ┆ a^2 │ + │ --- ┆ --- ┆ --- ┆ --- │ + │ i64 ┆ f64 ┆ bool ┆ f64 │ + ╞═════╪══════╪═══════╪══════╡ + │ 1 ┆ 0.5 ┆ true ┆ 1.0 │ + │ 2 ┆ 4.0 ┆ true ┆ 4.0 │ + │ 3 ┆ 10.0 ┆ false ┆ 9.0 │ + │ 4 ┆ 13.0 ┆ true ┆ 16.0 │ + └─────┴──────┴───────┴──────┘ + ``` + """ return super().with_columns(*exprs, **named_exprs) def select( From 4e69683edf3489b572efbeffdc1de86d6dbb1769 Mon Sep 17 00:00:00 2001 From: Franco Masotti Date: Wed, 27 Mar 2024 14:43:35 +0100 Subject: [PATCH 2/8] Add docstring - Add `narwhals.dataframe.DataFrame.columns` docstring - Fixed indentation in docstring --- narwhals/dataframe.py | 84 ++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/narwhals/dataframe.py b/narwhals/dataframe.py index e0b25cb25..1147d5d50 100644 --- a/narwhals/dataframe.py +++ b/narwhals/dataframe.py @@ -216,6 +216,41 @@ def schema(self) -> dict[str, DType]: @property def columns(self) -> list[str]: + r""" + Get or set column names. + + Examples: + Get column names. + ```python + >>> df_pl = pl.DataFrame( + ... { + ... "foo": [1, 2, 3], + ... "bar": [6, 7, 8], + ... "ham": ["a", "b", "c"], + ... } + ... ) + >>> df = nw.DataFrame(df_pl) + >>> df.columns + ['foo', 'bar', 'ham'] + ``` + + Set column names. + ```python + >>> df_pl = nw.to_native(df) + >>> df_pl.columns = ["apple", "banana", "orange"] + >>> df_pl + shape: (3, 3) + ┌───────┬────────┬────────┐ + │ apple ┆ banana ┆ orange │ + │ --- ┆ --- ┆ --- │ + │ i64 ┆ i64 ┆ str │ + ╞═══════╪════════╪════════╡ + │ 1 ┆ 6 ┆ a │ + │ 2 ┆ 7 ┆ b │ + │ 3 ┆ 8 ┆ c │ + └───────┴────────┴────────┘ + ``` + """ return super().columns def with_columns( @@ -241,30 +276,31 @@ def with_columns( Creating a new DataFrame using this method does not create a new copy of existing data. - Examples: Pass an expression to add it as a new column. - ```python - >>> df_pl = pl.DataFrame( - ... { - ... "a": [1, 2, 3, 4], - ... "b": [0.5, 4, 10, 13], - ... "c": [True, True, False, True], - ... } - ... ) - >>> df = nw.DataFrame(df_pl) - >>> df = df.with_columns((pl.col("a") ** 2).alias("a^2")) - >>> nw.to_native(df) - shape: (4, 4) - ┌─────┬──────┬───────┬──────┐ - │ a ┆ b ┆ c ┆ a^2 │ - │ --- ┆ --- ┆ --- ┆ --- │ - │ i64 ┆ f64 ┆ bool ┆ f64 │ - ╞═════╪══════╪═══════╪══════╡ - │ 1 ┆ 0.5 ┆ true ┆ 1.0 │ - │ 2 ┆ 4.0 ┆ true ┆ 4.0 │ - │ 3 ┆ 10.0 ┆ false ┆ 9.0 │ - │ 4 ┆ 13.0 ┆ true ┆ 16.0 │ - └─────┴──────┴───────┴──────┘ - ``` + Examples: + Pass an expression to add it as a new column. + ```python + >>> df_pl = pl.DataFrame( + ... { + ... "a": [1, 2, 3, 4], + ... "b": [0.5, 4, 10, 13], + ... "c": [True, True, False, True], + ... } + ... ) + >>> df = nw.DataFrame(df_pl) + >>> df = df.with_columns((pl.col("a") ** 2).alias("a^2")) + >>> nw.to_native(df) + shape: (4, 4) + ┌─────┬──────┬───────┬──────┐ + │ a ┆ b ┆ c ┆ a^2 │ + │ --- ┆ --- ┆ --- ┆ --- │ + │ i64 ┆ f64 ┆ bool ┆ f64 │ + ╞═════╪══════╪═══════╪══════╡ + │ 1 ┆ 0.5 ┆ true ┆ 1.0 │ + │ 2 ┆ 4.0 ┆ true ┆ 4.0 │ + │ 3 ┆ 10.0 ┆ false ┆ 9.0 │ + │ 4 ┆ 13.0 ┆ true ┆ 16.0 │ + └─────┴──────┴───────┴──────┘ + ``` """ return super().with_columns(*exprs, **named_exprs) From cbb858856c63b83fc28d4514e48b36ebe25f7dfb Mon Sep 17 00:00:00 2001 From: Franco Masotti Date: Thu, 28 Mar 2024 15:01:47 +0100 Subject: [PATCH 3/8] Add docstrings - Add more docstrings and fix existing --- narwhals/dataframe.py | 230 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 210 insertions(+), 20 deletions(-) diff --git a/narwhals/dataframe.py b/narwhals/dataframe.py index 1147d5d50..44beccde7 100644 --- a/narwhals/dataframe.py +++ b/narwhals/dataframe.py @@ -212,15 +212,33 @@ def to_dict(self, *, as_series: bool = True) -> dict[str, Any]: # inherited @property def schema(self) -> dict[str, DType]: + r""" + Get a dict[column name, DataType]. + + Examples: + ```python + >>> df_pl = pl.DataFrame( + ... { + ... "foo": [1, 2, 3], + ... "bar": [6.0, 7.0, 8.0], + ... "ham": ["a", "b", "c"], + ... } + ... ) + >>> df = nw.DataFrame(df_pl) + >>> df.schema + OrderedDict({'foo': Int64, 'bar': Float64, 'ham': String}) + ``` + """ return super().schema @property def columns(self) -> list[str]: r""" - Get or set column names. + Get column names. Examples: Get column names. + ```python >>> df_pl = pl.DataFrame( ... { @@ -233,23 +251,6 @@ def columns(self) -> list[str]: >>> df.columns ['foo', 'bar', 'ham'] ``` - - Set column names. - ```python - >>> df_pl = nw.to_native(df) - >>> df_pl.columns = ["apple", "banana", "orange"] - >>> df_pl - shape: (3, 3) - ┌───────┬────────┬────────┐ - │ apple ┆ banana ┆ orange │ - │ --- ┆ --- ┆ --- │ - │ i64 ┆ i64 ┆ str │ - ╞═══════╪════════╪════════╡ - │ 1 ┆ 6 ┆ a │ - │ 2 ┆ 7 ┆ b │ - │ 3 ┆ 8 ┆ c │ - └───────┴────────┴────────┘ - ``` """ return super().columns @@ -278,6 +279,7 @@ def with_columns( Examples: Pass an expression to add it as a new column. + ```python >>> df_pl = pl.DataFrame( ... { @@ -287,8 +289,13 @@ def with_columns( ... } ... ) >>> df = nw.DataFrame(df_pl) - >>> df = df.with_columns((pl.col("a") ** 2).alias("a^2")) - >>> nw.to_native(df) + >>> dframe = df.with_columns((pl.col("a") ** 2).alias("a^2")) + >>> dframe + ┌─────────────────────────────────────────────────┐ + | Narwhals DataFrame | + | Use `narwhals.to_native()` to see native output | + └─────────────────────────────────────────────────┘ + >>> nw.to_native(dframe) shape: (4, 4) ┌─────┬──────┬───────┬──────┐ │ a ┆ b ┆ c ┆ a^2 │ @@ -309,9 +316,192 @@ def select( *exprs: IntoExpr | Iterable[IntoExpr], **named_exprs: IntoExpr, ) -> Self: + r""" + Select columns from this DataFrame. + + Arguments: + *exprs: Column(s) to select, specified as positional arguments. + Accepts expression input. Strings are parsed as column names, + other non-expression inputs are parsed as literals. + + **named_exprs: Additional columns to select, specified as keyword arguments. + The columns will be renamed to the keyword used. + + Examples: + Pass the name of a column to select that column. + + ```python + >>> df_pl = pl.DataFrame( + ... { + ... "foo": [1, 2, 3], + ... "bar": [6, 7, 8], + ... "ham": ["a", "b", "c"], + ... } + ... ) + >>> df = nw.DataFrame(df_pl) + >>> dframe = df.select("foo") + >>> dframe + ┌─────────────────────────────────────────────────┐ + | Narwhals DataFrame | + | Use `narwhals.to_native()` to see native output | + └─────────────────────────────────────────────────┘ + >>> nw.to_native(dframe) + shape: (3, 1) + ┌─────┐ + │ foo │ + │ --- │ + │ i64 │ + ╞═════╡ + │ 1 │ + │ 2 │ + │ 3 │ + └─────┘ + ``` + + Multiple columns can be selected by passing a list of column names. + + ```python + >>> dframe = df.select(["foo", "bar"]) + >>> dframe + ┌─────────────────────────────────────────────────┐ + | Narwhals DataFrame | + | Use `narwhals.to_native()` to see native output | + └─────────────────────────────────────────────────┘ + >>> nw.to_native(dframe) + shape: (3, 2) + ┌─────┬─────┐ + │ foo ┆ bar │ + │ --- ┆ --- │ + │ i64 ┆ i64 │ + ╞═════╪═════╡ + │ 1 ┆ 6 │ + │ 2 ┆ 7 │ + │ 3 ┆ 8 │ + └─────┴─────┘ + ``` + + Multiple columns can also be selected using positional arguments instead of a + list. Expressions are also accepted. + + ```python + >>> dframe = df.select(pl.col("foo"), pl.col("bar") + 1) + ┌─────────────────────────────────────────────────┐ + | Narwhals DataFrame | + | Use `narwhals.to_native()` to see native output | + └─────────────────────────────────────────────────┘ + >>> nw.to_native(dframe) + shape: (3, 2) + ┌─────┬─────┐ + │ foo ┆ bar │ + │ --- ┆ --- │ + │ i64 ┆ i64 │ + ╞═════╪═════╡ + │ 1 ┆ 7 │ + │ 2 ┆ 8 │ + │ 3 ┆ 9 │ + └─────┴─────┘ + ``` + + Use keyword arguments to easily name your expression inputs. + + ```python + >>> dframe = df.select(threshold=pl.when(pl.col("foo") > 2).then(10).otherwise(0)) + >>> dframe + ┌─────────────────────────────────────────────────┐ + | Narwhals DataFrame | + | Use `narwhals.to_native()` to see native output | + └─────────────────────────────────────────────────┘ + >>> nw.to_native(dframe) + shape: (3, 1) + ┌───────────┐ + │ threshold │ + │ --- │ + │ i32 │ + ╞═══════════╡ + │ 0 │ + │ 0 │ + │ 10 │ + └───────────┘ + ``` + + Expressions with multiple outputs can be automatically instantiated as Structs + by enabling the setting `Config.set_auto_structify(True)`: + + ```python + >>> with pl.Config(auto_structify=True): + ... dframe = df.select( + ... is_odd=(pl.col(pl.INTEGER_DTYPES) % 2).name.suffix("_is_odd"), + ... ) + >>> dframe + ┌─────────────────────────────────────────────────┐ + | Narwhals DataFrame | + | Use `narwhals.to_native()` to see native output | + └─────────────────────────────────────────────────┘ + >>> nw.to_native(dframe) + shape: (3, 1) + ┌───────────┐ + │ is_odd │ + │ --- │ + │ struct[2] │ + ╞═══════════╡ + │ {1,0} │ + │ {0,1} │ + │ {1,0} │ + └───────────┘ + ``` + """ return super().select(*exprs, **named_exprs) def rename(self, mapping: dict[str, str]) -> Self: + r""" + Rename column names. + + Arguments: + mapping: Key value pairs that map from old name to new name, or a function + that takes the old name as input and returns the new name. + + Examples: + ```python + >>> df_pl = pl.DataFrame( + ... {"foo": [1, 2, 3], "bar": [6, 7, 8], "ham": ["a", "b", "c"]} + ... ) + >>> df = nw.DataFrame(df_pl) + >>> dframe = df.rename({"foo": "apple"}) + >>> dframe + ┌─────────────────────────────────────────────────┐ + | Narwhals DataFrame | + | Use `narwhals.to_native()` to see native output | + └─────────────────────────────────────────────────┘ + >>> nw.to_native(dframe) + shape: (3, 3) + ┌───────┬─────┬─────┐ + │ apple ┆ bar ┆ ham │ + │ --- ┆ --- ┆ --- │ + │ i64 ┆ i64 ┆ str │ + ╞═══════╪═════╪═════╡ + │ 1 ┆ 6 ┆ a │ + │ 2 ┆ 7 ┆ b │ + │ 3 ┆ 8 ┆ c │ + └───────┴─────┴─────┘ + >>> dframe = df.rename(lambda column_name: "c" + column_name[1:]) + >>> dframe + ┌─────────────────────────────────────────────────┐ + | Narwhals DataFrame | + | Use `narwhals.to_native()` to see native output | + └─────────────────────────────────────────────────┘ + >>> nw.to_native(dframe) + shape: (3, 3) + ┌─────┬─────┬─────┐ + │ coo ┆ car ┆ cam │ + │ --- ┆ --- ┆ --- │ + │ i64 ┆ i64 ┆ str │ + ╞═════╪═════╪═════╡ + │ 1 ┆ 6 ┆ a │ + │ 2 ┆ 7 ┆ b │ + │ 3 ┆ 8 ┆ c │ + └─────┴─────┴─────┘ + ``` + """ return super().rename(mapping) def head(self, n: int) -> Self: From a855860b56ac8496d3212cd890ce03232459c5a9 Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:26:52 +0000 Subject: [PATCH 4/8] fixup --- narwhals/dataframe.py | 64 +++++++++++++++---------------------------- narwhals/series.py | 2 +- 2 files changed, 23 insertions(+), 43 deletions(-) diff --git a/narwhals/dataframe.py b/narwhals/dataframe.py index 44beccde7..3167e27cf 100644 --- a/narwhals/dataframe.py +++ b/narwhals/dataframe.py @@ -69,7 +69,7 @@ def __repr__(self) -> str: # pragma: no cover + "| Use `narwhals.to_native()` to see native output |\n" + "└" + "─" * length - + "┘\n" + + "┘" ) @property @@ -217,6 +217,8 @@ def schema(self) -> dict[str, DType]: Examples: ```python + >>> import polars as pl + >>> import narwhals as nw >>> df_pl = pl.DataFrame( ... { ... "foo": [1, 2, 3], @@ -225,7 +227,7 @@ def schema(self) -> dict[str, DType]: ... } ... ) >>> df = nw.DataFrame(df_pl) - >>> df.schema + >>> df.schema # doctest: +SKIP OrderedDict({'foo': Int64, 'bar': Float64, 'ham': String}) ``` """ @@ -240,6 +242,8 @@ def columns(self) -> list[str]: Get column names. ```python + >>> import polars as pl + >>> import narwhals as nw >>> df_pl = pl.DataFrame( ... { ... "foo": [1, 2, 3], @@ -250,7 +254,6 @@ def columns(self) -> list[str]: >>> df = nw.DataFrame(df_pl) >>> df.columns ['foo', 'bar', 'ham'] - ``` """ return super().columns @@ -281,6 +284,8 @@ def with_columns( Pass an expression to add it as a new column. ```python + >>> import polars as pl + >>> import narwhals as nw >>> df_pl = pl.DataFrame( ... { ... "a": [1, 2, 3, 4], @@ -295,6 +300,7 @@ def with_columns( | Narwhals DataFrame | | Use `narwhals.to_native()` to see native output | └─────────────────────────────────────────────────┘ + >>> nw.to_native(dframe) shape: (4, 4) ┌─────┬──────┬───────┬──────┐ @@ -307,7 +313,6 @@ def with_columns( │ 3 ┆ 10.0 ┆ false ┆ 9.0 │ │ 4 ┆ 13.0 ┆ true ┆ 16.0 │ └─────┴──────┴───────┴──────┘ - ``` """ return super().with_columns(*exprs, **named_exprs) @@ -331,6 +336,8 @@ def select( Pass the name of a column to select that column. ```python + >>> import polars as pl + >>> import narwhals as nw >>> df_pl = pl.DataFrame( ... { ... "foo": [1, 2, 3], @@ -356,7 +363,6 @@ def select( │ 2 │ │ 3 │ └─────┘ - ``` Multiple columns can be selected by passing a list of column names. @@ -378,13 +384,13 @@ def select( │ 2 ┆ 7 │ │ 3 ┆ 8 │ └─────┴─────┘ - ``` Multiple columns can also be selected using positional arguments instead of a list. Expressions are also accepted. ```python >>> dframe = df.select(pl.col("foo"), pl.col("bar") + 1) + >>> dframe ┌─────────────────────────────────────────────────┐ | Narwhals DataFrame | | Use `narwhals.to_native()` to see native output | @@ -400,12 +406,11 @@ def select( │ 2 ┆ 8 │ │ 3 ┆ 9 │ └─────┴─────┘ - ``` Use keyword arguments to easily name your expression inputs. ```python - >>> dframe = df.select(threshold=pl.when(pl.col("foo") > 2).then(10).otherwise(0)) + >>> dframe = df.select(threshold=nw.col('foo')*2) >>> dframe ┌─────────────────────────────────────────────────┐ | Narwhals DataFrame | @@ -416,39 +421,12 @@ def select( ┌───────────┐ │ threshold │ │ --- │ - │ i32 │ + │ i64 │ ╞═══════════╡ - │ 0 │ - │ 0 │ - │ 10 │ + │ 2 │ + │ 4 │ + │ 6 │ └───────────┘ - ``` - - Expressions with multiple outputs can be automatically instantiated as Structs - by enabling the setting `Config.set_auto_structify(True)`: - - ```python - >>> with pl.Config(auto_structify=True): - ... dframe = df.select( - ... is_odd=(pl.col(pl.INTEGER_DTYPES) % 2).name.suffix("_is_odd"), - ... ) - >>> dframe - ┌─────────────────────────────────────────────────┐ - | Narwhals DataFrame | - | Use `narwhals.to_native()` to see native output | - └─────────────────────────────────────────────────┘ - >>> nw.to_native(dframe) - shape: (3, 1) - ┌───────────┐ - │ is_odd │ - │ --- │ - │ struct[2] │ - ╞═══════════╡ - │ {1,0} │ - │ {0,1} │ - │ {1,0} │ - └───────────┘ - ``` """ return super().select(*exprs, **named_exprs) @@ -462,6 +440,8 @@ def rename(self, mapping: dict[str, str]) -> Self: Examples: ```python + >>> import polars as pl + >>> import narwhals as nw >>> df_pl = pl.DataFrame( ... {"foo": [1, 2, 3], "bar": [6, 7, 8], "ham": ["a", "b", "c"]} ... ) @@ -472,6 +452,7 @@ def rename(self, mapping: dict[str, str]) -> Self: | Narwhals DataFrame | | Use `narwhals.to_native()` to see native output | └─────────────────────────────────────────────────┘ + >>> nw.to_native(dframe) shape: (3, 3) ┌───────┬─────┬─────┐ @@ -483,7 +464,7 @@ def rename(self, mapping: dict[str, str]) -> Self: │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ └───────┴─────┴─────┘ - >>> dframe = df.rename(lambda column_name: "c" + column_name[1:]) + >>> dframe = df.rename(lambda column_name: "f" + column_name[1:]) >>> dframe ┌─────────────────────────────────────────────────┐ | Narwhals DataFrame | @@ -492,7 +473,7 @@ def rename(self, mapping: dict[str, str]) -> Self: >>> nw.to_native(dframe) shape: (3, 3) ┌─────┬─────┬─────┐ - │ coo ┆ car ┆ cam │ + │ foo ┆ far ┆ fam │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ str │ ╞═════╪═════╪═════╡ @@ -500,7 +481,6 @@ def rename(self, mapping: dict[str, str]) -> Self: │ 2 ┆ 7 ┆ b │ │ 3 ┆ 8 ┆ c │ └─────┴─────┴─────┘ - ``` """ return super().rename(mapping) diff --git a/narwhals/series.py b/narwhals/series.py index fc4c442ed..8621d6158 100644 --- a/narwhals/series.py +++ b/narwhals/series.py @@ -61,7 +61,7 @@ def __repr__(self) -> str: # pragma: no cover + "| Use `narwhals.to_native()` to see native output |\n" + "└" + "─" * length - + "┘\n" + + "┘" ) def alias(self, name: str) -> Self: From 93603004b32acfd0769dd3110270bd85c5920ba0 Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:27:24 +0000 Subject: [PATCH 5/8] revert .gitignore changes --- .gitignore | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.gitignore b/.gitignore index 01d41e44c..9a2584d6f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,3 @@ todo.md .coverage site/ .coverage.* - -Makefile -requirements-freeze.txt -.requirements-freeze-hashes.txt -.project.mk From 40baa56183635a35be3dde36ab301d5679ecd4a7 Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:28:55 +0000 Subject: [PATCH 6/8] use narhwals expressions --- narwhals/dataframe.py | 4 ++-- narwhals/pandas_like/group_by.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/narwhals/dataframe.py b/narwhals/dataframe.py index 3167e27cf..028b4cea5 100644 --- a/narwhals/dataframe.py +++ b/narwhals/dataframe.py @@ -294,7 +294,7 @@ def with_columns( ... } ... ) >>> df = nw.DataFrame(df_pl) - >>> dframe = df.with_columns((pl.col("a") ** 2).alias("a^2")) + >>> dframe = df.with_columns((nw.col("a") ** 2).alias("a^2")) >>> dframe ┌─────────────────────────────────────────────────┐ | Narwhals DataFrame | @@ -389,7 +389,7 @@ def select( list. Expressions are also accepted. ```python - >>> dframe = df.select(pl.col("foo"), pl.col("bar") + 1) + >>> dframe = df.select(nw.col("foo"), nw.col("bar") + 1) >>> dframe ┌─────────────────────────────────────────────────┐ | Narwhals DataFrame | diff --git a/narwhals/pandas_like/group_by.py b/narwhals/pandas_like/group_by.py index 0170f5cde..b579ef0e8 100644 --- a/narwhals/pandas_like/group_by.py +++ b/narwhals/pandas_like/group_by.py @@ -47,8 +47,8 @@ def agg( if expr._output_names is None: msg = ( "Anonymous expressions are not supported in group_by.agg.\n" - "Instead of `pl.all()`, try using a named expression, such as " - "`pl.col('a', 'b')`\n" + "Instead of `nw.all()`, try using a named expression, such as " + "`nw.col('a', 'b')`\n" ) raise ValueError(msg) output_names.extend(expr._output_names) From 2c760a4f6e33f3ccb2819b9706b2b7324bd9cd49 Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:33:38 +0000 Subject: [PATCH 7/8] run doctests in CI --- .github/workflows/pytest.yml | 2 ++ narwhals/dataframe.py | 30 +++++++++++------------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index a20e5e6c1..c52f349c4 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -32,3 +32,5 @@ jobs: run: python -m pip install --upgrade modin[dask] - name: Run pytest run: pytest tests --cov=narwhals --cov=tests --cov-fail-under=50 + - name: Run doctests + run: pytest narwhals --doctest-modules diff --git a/narwhals/dataframe.py b/narwhals/dataframe.py index 028b4cea5..300c68ddb 100644 --- a/narwhals/dataframe.py +++ b/narwhals/dataframe.py @@ -216,7 +216,6 @@ def schema(self) -> dict[str, DType]: Get a dict[column name, DataType]. Examples: - ```python >>> import polars as pl >>> import narwhals as nw >>> df_pl = pl.DataFrame( @@ -241,7 +240,6 @@ def columns(self) -> list[str]: Examples: Get column names. - ```python >>> import polars as pl >>> import narwhals as nw >>> df_pl = pl.DataFrame( @@ -283,7 +281,6 @@ def with_columns( Examples: Pass an expression to add it as a new column. - ```python >>> import polars as pl >>> import narwhals as nw >>> df_pl = pl.DataFrame( @@ -294,7 +291,7 @@ def with_columns( ... } ... ) >>> df = nw.DataFrame(df_pl) - >>> dframe = df.with_columns((nw.col("a") ** 2).alias("a^2")) + >>> dframe = df.with_columns((nw.col("a") * 2).alias("a*2")) >>> dframe ┌─────────────────────────────────────────────────┐ | Narwhals DataFrame | @@ -303,16 +300,16 @@ def with_columns( >>> nw.to_native(dframe) shape: (4, 4) - ┌─────┬──────┬───────┬──────┐ - │ a ┆ b ┆ c ┆ a^2 │ - │ --- ┆ --- ┆ --- ┆ --- │ - │ i64 ┆ f64 ┆ bool ┆ f64 │ - ╞═════╪══════╪═══════╪══════╡ - │ 1 ┆ 0.5 ┆ true ┆ 1.0 │ - │ 2 ┆ 4.0 ┆ true ┆ 4.0 │ - │ 3 ┆ 10.0 ┆ false ┆ 9.0 │ - │ 4 ┆ 13.0 ┆ true ┆ 16.0 │ - └─────┴──────┴───────┴──────┘ + ┌─────┬──────┬───────┬─────┐ + │ a ┆ b ┆ c ┆ a*2 │ + │ --- ┆ --- ┆ --- ┆ --- │ + │ i64 ┆ f64 ┆ bool ┆ i64 │ + ╞═════╪══════╪═══════╪═════╡ + │ 1 ┆ 0.5 ┆ true ┆ 2 │ + │ 2 ┆ 4.0 ┆ true ┆ 4 │ + │ 3 ┆ 10.0 ┆ false ┆ 6 │ + │ 4 ┆ 13.0 ┆ true ┆ 8 │ + └─────┴──────┴───────┴─────┘ """ return super().with_columns(*exprs, **named_exprs) @@ -335,7 +332,6 @@ def select( Examples: Pass the name of a column to select that column. - ```python >>> import polars as pl >>> import narwhals as nw >>> df_pl = pl.DataFrame( @@ -366,7 +362,6 @@ def select( Multiple columns can be selected by passing a list of column names. - ```python >>> dframe = df.select(["foo", "bar"]) >>> dframe ┌─────────────────────────────────────────────────┐ @@ -388,7 +383,6 @@ def select( Multiple columns can also be selected using positional arguments instead of a list. Expressions are also accepted. - ```python >>> dframe = df.select(nw.col("foo"), nw.col("bar") + 1) >>> dframe ┌─────────────────────────────────────────────────┐ @@ -409,7 +403,6 @@ def select( Use keyword arguments to easily name your expression inputs. - ```python >>> dframe = df.select(threshold=nw.col('foo')*2) >>> dframe ┌─────────────────────────────────────────────────┐ @@ -439,7 +432,6 @@ def rename(self, mapping: dict[str, str]) -> Self: that takes the old name as input and returns the new name. Examples: - ```python >>> import polars as pl >>> import narwhals as nw >>> df_pl = pl.DataFrame( From bfbeec534a886949b3161dcc893a524be72e24fb Mon Sep 17 00:00:00 2001 From: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:36:33 +0000 Subject: [PATCH 8/8] py<3.10 compat --- narwhals/pandas_like/typing.py | 3 ++- narwhals/typing.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/narwhals/pandas_like/typing.py b/narwhals/pandas_like/typing.py index 89b0051b4..1d2c1b9f4 100644 --- a/narwhals/pandas_like/typing.py +++ b/narwhals/pandas_like/typing.py @@ -1,9 +1,10 @@ from __future__ import annotations from typing import TYPE_CHECKING -from typing import TypeAlias if TYPE_CHECKING: + from typing import TypeAlias + from narwhals.pandas_like.expr import PandasExpr from narwhals.pandas_like.series import PandasSeries diff --git a/narwhals/typing.py b/narwhals/typing.py index 2504e85a3..1f06366b5 100644 --- a/narwhals/typing.py +++ b/narwhals/typing.py @@ -1,8 +1,9 @@ from typing import TYPE_CHECKING -from typing import TypeAlias from typing import TypeVar if TYPE_CHECKING: + from typing import TypeAlias + from narwhals.expression import Expr from narwhals.series import Series