Skip to content

Commit

Permalink
docstring, deprecation
Browse files Browse the repository at this point in the history
  • Loading branch information
FBruzzesi committed Nov 1, 2024
1 parent 6ad4c4b commit 783865a
Show file tree
Hide file tree
Showing 6 changed files with 291 additions and 13 deletions.
2 changes: 1 addition & 1 deletion docs/basics/dataframe_conversion.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Similarly, if your library uses Polars internally, you can convert any user-supp

```python exec="1" source="above" session="conversion" result="python"
def df_to_polars(df: IntoDataFrame) -> pl.DataFrame:
return nw.from_arrow(nw.from_native(df), native_namespace=pl).to_native()
return nw.from_arrow(nw.from_native(df), native_namespace=pl).native


print(df_to_polars(df_duckdb)) # You can only execute this line of code once.
Expand Down
105 changes: 96 additions & 9 deletions narwhals/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
from typing import Sequence
from typing import TypeVar
from typing import overload
from warnings import warn

from narwhals.dependencies import get_polars
from narwhals.dependencies import is_numpy_array
from narwhals.schema import Schema
from narwhals.translate import to_native
from narwhals.utils import flatten
from narwhals.utils import is_sequence_but_not_str
from narwhals.utils import parse_version
Expand Down Expand Up @@ -330,7 +330,50 @@ def _lazyframe(self) -> type[LazyFrame[Any]]:

@property
def native(self: Self) -> DataFrameT:
"""Returns native frame underlying Narwhals DataFrame."""
"""
Convert Narwhals DataFrame to native one.
Returns:
Object of class that user started with.
Examples:
>>> import pandas as pd
>>> import polars as pl
>>> import pyarrow as pa
>>> import narwhals as nw
>>> data = {"foo": [1, 2, 3], "bar": [6.0, 7.0, 8.0], "ham": ["a", "b", "c"]}
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)
>>> df_pa = pa.table(data)
Calling `to_native` on a Narwhals DataFrame returns the native object:
>>> nw.from_native(df_pd).to_native()
foo bar ham
0 1 6.0 a
1 2 7.0 b
2 3 8.0 c
>>> nw.from_native(df_pl).to_native()
shape: (3, 3)
┌─────┬─────┬─────┐
│ foo ┆ bar ┆ ham │
│ --- ┆ --- ┆ --- │
│ i64 ┆ f64 ┆ str │
╞═════╪═════╪═════╡
│ 1 ┆ 6.0 ┆ a │
│ 2 ┆ 7.0 ┆ b │
│ 3 ┆ 8.0 ┆ c │
└─────┴─────┴─────┘
>>> nw.from_native(df_pa).to_native()
pyarrow.Table
foo: int64
bar: double
ham: string
----
foo: [[1,2,3]]
bar: [[6,7,8]]
ham: [["a","b","c"]]
"""
return self._compliant_frame._native_frame # type: ignore[no-any-return]

def __init__(
Expand Down Expand Up @@ -435,7 +478,7 @@ def lazy(self) -> LazyFrame[Any]:
"""
return self._lazyframe(self._compliant_frame.lazy(), level=self._level)

def to_native(self) -> DataFrameT:
def to_native(self: Self) -> DataFrameT:
"""
Convert Narwhals DataFrame to native one.
Expand Down Expand Up @@ -480,8 +523,13 @@ def to_native(self) -> DataFrameT:
bar: [[6,7,8]]
ham: [["a","b","c"]]
"""

return self._compliant_frame._native_frame # type: ignore[no-any-return]
warn(
"Use `.native` property instead. `.to_native()` is "
"deprecated and it will be removed in future versions",
DeprecationWarning,
stacklevel=2,
)
return self.native

def to_pandas(self) -> pd.DataFrame:
"""
Expand Down Expand Up @@ -2772,7 +2820,41 @@ def _dataframe(self) -> type[DataFrame[Any]]:

@property
def native(self: Self) -> FrameT:
"""Returns native frame underlying Narwhals LazyFrame."""
"""
Convert Narwhals LazyFrame to native one.
Returns:
Object of class that user started with.
Examples:
>>> import pandas as pd
>>> import polars as pl
>>> import pyarrow as pa
>>> import narwhals as nw
>>> data = {"foo": [1, 2, 3], "bar": [6.0, 7.0, 8.0], "ham": ["a", "b", "c"]}
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.LazyFrame(data)
>>> df_pa = pa.table(data)
Calling `to_native` on a Narwhals DataFrame returns the native object:
>>> nw.from_native(df_pd).lazy().to_native()
foo bar ham
0 1 6.0 a
1 2 7.0 b
2 3 8.0 c
>>> nw.from_native(df_pl).to_native().collect()
shape: (3, 3)
┌─────┬─────┬─────┐
│ foo ┆ bar ┆ ham │
│ --- ┆ --- ┆ --- │
│ i64 ┆ f64 ┆ str │
╞═════╪═════╪═════╡
│ 1 ┆ 6.0 ┆ a │
│ 2 ┆ 7.0 ┆ b │
│ 3 ┆ 8.0 ┆ c │
└─────┴─────┴─────┘
"""
return self._compliant_frame._native_frame # type: ignore[no-any-return]

def __init__(
Expand Down Expand Up @@ -2847,7 +2929,7 @@ def collect(self) -> DataFrame[Any]:
level=self._level,
)

def to_native(self) -> FrameT:
def to_native(self: Self) -> FrameT:
"""
Convert Narwhals LazyFrame to native one.
Expand Down Expand Up @@ -2883,8 +2965,13 @@ def to_native(self) -> FrameT:
│ 3 ┆ 8.0 ┆ c │
└─────┴─────┴─────┘
"""

return to_native(narwhals_object=self, strict=True)
warn(
"Use `.native` property instead. `.to_native()` is "
"deprecated and it will be removed in future versions",
DeprecationWarning,
stacklevel=2,
)
return self.native

# inherited
def pipe(self, function: Callable[[Any], Self], *args: Any, **kwargs: Any) -> Self:
Expand Down
48 changes: 45 additions & 3 deletions narwhals/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from typing import Sequence
from typing import TypeVar
from typing import overload
from warnings import warn

from narwhals.utils import parse_version

Expand Down Expand Up @@ -43,7 +44,42 @@ def _dataframe(self) -> type[DataFrame[Any]]:

@property
def native(self: Self) -> Any:
"""Returns native series underlying Narwhals Series."""
"""
Convert Narwhals series to native series.
Returns:
Series of class that user started with.
Examples:
>>> import pandas as pd
>>> import polars as pl
>>> import narwhals as nw
>>> s = [1, 2, 3]
>>> s_pd = pd.Series(s)
>>> s_pl = pl.Series(s)
We define a library agnostic function:
>>> @nw.narwhalify
... def func(s):
... return s.to_native()
We can then pass either pandas or Polars to `func`:
>>> func(s_pd)
0 1
1 2
2 3
dtype: int64
>>> func(s_pl) # doctest: +NORMALIZE_WHITESPACE
shape: (3,)
Series: '' [i64]
[
1
2
3
]
"""
return self._compliant_series._native_series

def __init__(
Expand Down Expand Up @@ -102,7 +138,7 @@ def __arrow_c_stream__(self, requested_schema: object | None = None) -> object:
ca = pa.chunked_array([self.to_arrow()])
return ca.__arrow_c_stream__(requested_schema=requested_schema)

def to_native(self) -> Any:
def to_native(self: Self) -> Any:
"""
Convert Narwhals series to native series.
Expand Down Expand Up @@ -139,7 +175,13 @@ def to_native(self) -> Any:
3
]
"""
return self._compliant_series._native_series
warn(
"Use `.native` property instead. `.to_native()` is "
"deprecated and it will be removed in future versions",
DeprecationWarning,
stacklevel=2,
)
return self.native

def scatter(self, indices: int | Sequence[int], values: Any) -> Self:
"""
Expand Down
124 changes: 124 additions & 0 deletions narwhals/stable/v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,53 @@ def is_unique(self: Self) -> Series:
"""
return super().is_unique() # type: ignore[return-value]

def to_native(self: Self) -> IntoDataFrameT:
"""
Convert Narwhals DataFrame to native one.
Returns:
Object of class that user started with.
Examples:
>>> import pandas as pd
>>> import polars as pl
>>> import pyarrow as pa
>>> import narwhals as nw
>>> data = {"foo": [1, 2, 3], "bar": [6.0, 7.0, 8.0], "ham": ["a", "b", "c"]}
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)
>>> df_pa = pa.table(data)
Calling `to_native` on a Narwhals DataFrame returns the native object:
>>> nw.from_native(df_pd).to_native()
foo bar ham
0 1 6.0 a
1 2 7.0 b
2 3 8.0 c
>>> nw.from_native(df_pl).to_native()
shape: (3, 3)
┌─────┬─────┬─────┐
│ foo ┆ bar ┆ ham │
│ --- ┆ --- ┆ --- │
│ i64 ┆ f64 ┆ str │
╞═════╪═════╪═════╡
│ 1 ┆ 6.0 ┆ a │
│ 2 ┆ 7.0 ┆ b │
│ 3 ┆ 8.0 ┆ c │
└─────┴─────┴─────┘
>>> nw.from_native(df_pa).to_native()
pyarrow.Table
foo: int64
bar: double
ham: string
----
foo: [[1,2,3]]
bar: [[6,7,8]]
ham: [["a","b","c"]]
"""
return self.native

def _l1_norm(self: Self) -> Self:
"""Private, just used to test the stable API."""
return self.select(all()._l1_norm())
Expand Down Expand Up @@ -383,6 +430,44 @@ def collect(self) -> DataFrame[Any]:
"""
return super().collect() # type: ignore[return-value]

def to_native(self: Self) -> IntoFrameT:
"""
Convert Narwhals LazyFrame to native one.
Returns:
Object of class that user started with.
Examples:
>>> import pandas as pd
>>> import polars as pl
>>> import pyarrow as pa
>>> import narwhals.stable.v1 as nw
>>> data = {"foo": [1, 2, 3], "bar": [6.0, 7.0, 8.0], "ham": ["a", "b", "c"]}
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.LazyFrame(data)
>>> df_pa = pa.table(data)
Calling `to_native` on a Narwhals DataFrame returns the native object:
>>> nw.from_native(df_pd).lazy().to_native()
foo bar ham
0 1 6.0 a
1 2 7.0 b
2 3 8.0 c
>>> nw.from_native(df_pl).to_native().collect()
shape: (3, 3)
┌─────┬─────┬─────┐
│ foo ┆ bar ┆ ham │
│ --- ┆ --- ┆ --- │
│ i64 ┆ f64 ┆ str │
╞═════╪═════╪═════╡
│ 1 ┆ 6.0 ┆ a │
│ 2 ┆ 7.0 ┆ b │
│ 3 ┆ 8.0 ┆ c │
└─────┴─────┴─────┘
"""
return self.native

def _l1_norm(self: Self) -> Self:
"""Private, just used to test the stable API."""
return self.select(all()._l1_norm())
Expand Down Expand Up @@ -501,6 +586,45 @@ def value_counts(
sort=sort, parallel=parallel, name=name, normalize=normalize
)

def to_native(self: Self) -> Any:
"""
Convert Narwhals series to native series.
Returns:
Series of class that user started with.
Examples:
>>> import pandas as pd
>>> import polars as pl
>>> import narwhals as nw
>>> s = [1, 2, 3]
>>> s_pd = pd.Series(s)
>>> s_pl = pl.Series(s)
We define a library agnostic function:
>>> @nw.narwhalify
... def func(s):
... return s.to_native()
We can then pass either pandas or Polars to `func`:
>>> func(s_pd)
0 1
1 2
2 3
dtype: int64
>>> func(s_pl) # doctest: +NORMALIZE_WHITESPACE
shape: (3,)
Series: '' [i64]
[
1
2
3
]
"""
return self.native


class Expr(NwExpr):
def _l1_norm(self) -> Self:
Expand Down
Loading

0 comments on commit 783865a

Please sign in to comment.