Skip to content

Commit

Permalink
redesign
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcoGorelli committed Mar 11, 2024
1 parent c380697 commit 5df15be
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 59 deletions.
2 changes: 2 additions & 0 deletions narwhals/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from narwhals.containers import is_pandas
from narwhals.containers import is_polars
from narwhals.containers import is_series
from narwhals.expressions import col
from narwhals.translate import get_namespace
from narwhals.translate import to_native
from narwhals.translate import translate_any
Expand All @@ -22,4 +23,5 @@
"get_implementation",
"get_namespace",
"to_native",
"col",
]
Empty file added narwhals/dataframe.py
Empty file.
105 changes: 105 additions & 0 deletions narwhals/expression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
from __future__ import annotations
from typing import Callable, Any

def extract_native(expr, other: Any) -> Any:
if isinstance(other, NarwhalsExpr):
return other._call(expr)
return other

class NarwhalsExpr:
def __init__(self, call: str):
self._call = call

# --- convert ---
def alias(self, name: str) -> Self:
return self.__class__(self._expr.alias(name))

def cast(
self,
dtype: DType, # type: ignore[override]
) -> Self:
return self.__class__(self._expr.cast(reverse_translate_dtype(dtype)))

# --- binary ---
def __eq__(self, other: object) -> Expr: # type: ignore[override]
return self.__class__(self._expr.__eq__(extract_native(other)))

def __and__(self, other: Any) -> Expr:
return self.__class__(self._expr.__and__(extract_native(other)))

def __or__(self, other: Any) -> Expr:
return self.__class__(self._expr.__or__(extract_native(other)))

def __add__(self, other):
return self.__class__(lambda expr: self._call(expr).__add__(extract_native(expr, other)))

def __radd__(self, other: Any) -> Expr:
return self.__class__(self._expr.__radd__(extract_native(other)))

def __sub__(self, other: Any) -> Expr:
return self.__class__(self._expr.__sub__(extract_native(other)))

def __rsub__(self, other: Any) -> Expr:
return self.__class__(self._expr.__rsub__(extract_native(other)))

def __mul__(self, other: Any) -> Expr:
return self.__class__(self._expr.__mul__(extract_native(other)))

def __rmul__(self, other: Any) -> Expr:
return self.__class__(self._expr.__rmul__(extract_native(other)))

def __le__(self, other: Any) -> Expr:
return self.__class__(self._expr.__le__(extract_native(other)))

def __lt__(self, other: Any) -> Expr:
return self.__class__(self._expr.__lt__(extract_native(other)))

def __gt__(self, other: Any) -> Expr:
return self.__class__(self._expr.__gt__(extract_native(other)))

def __ge__(self, other: Any) -> Expr:
return self.__class__(self._expr.__ge__(extract_native(other)))

# --- unary ---
def mean(self) -> Expr:
return self.__class__(self._expr.mean())

def sum(self) -> Expr:
return self.__class__(self._expr.sum())

def min(self) -> Expr:
return self.__class__(self._expr.min())

def max(self) -> Expr:
return self.__class__(self._expr.max())

def n_unique(self) -> Expr:
return self.__class__(self._expr.n_unique())

def unique(self) -> Expr:
return self.__class__(self._expr.unique())

# --- transform ---
def is_between(
self, lower_bound: Any, upper_bound: Any, closed: str = "both"
) -> Expr:
return self.__class__(self._expr.is_between(lower_bound, upper_bound, closed)) # type: ignore[arg-type]

def is_in(self, other: Any) -> Expr:
return self.__class__(self._expr.is_in(other))

def is_null(self) -> Expr:
return self.__class__(self._expr.is_null())

# --- partial reduction ---
def drop_nulls(self) -> Expr:
return self.__class__(self._expr.drop_nulls())

def sample(self, n: int, fraction: float, *, with_replacement: bool) -> Expr:
return self.__class__(
self._expr.sample(n, fraction=fraction, with_replacement=with_replacement)
)


def col(col_name: str):
return NarwhalsExpr(lambda expr: expr(col_name))
4 changes: 2 additions & 2 deletions narwhals/pandas_like/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def select(
) -> Self:
new_series = evaluate_into_exprs(self, *exprs, **named_exprs)
df = horizontal_concat(
[series.series for series in new_series],
[series._series for series in new_series],
implementation=self._implementation,
)
return self._from_dataframe(df)
Expand All @@ -137,7 +137,7 @@ def with_columns(
) -> Self:
new_series = evaluate_into_exprs(self, *exprs, **named_exprs)
df = self._dataframe.assign(
**{series.name: series.series for series in new_series}
**{series.name: series._series for series in new_series}
)
return self._from_dataframe(df)

Expand Down
4 changes: 2 additions & 2 deletions narwhals/pandas_like/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ def ends_with(self, suffix: str) -> Expr:
return Expr(
lambda df: [
PandasSeries(
series.series.str.endswith(suffix),
series._series.str.endswith(suffix),
implementation=df._implementation,
)
for series in self._expr._call(df)
Expand All @@ -229,7 +229,7 @@ def strip_chars(self, characters: str = " ") -> Expr:
return Expr(
lambda df: [
PandasSeries(
series.series.str.strip(characters),
series._series.str.strip(characters),
implementation=df._implementation,
)
for series in self._expr._call(df)
Expand Down
4 changes: 2 additions & 2 deletions narwhals/pandas_like/namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ def _create_series_from_scalar(
return PandasSeries(
series_from_iterable(
[value],
name=series.series.name,
index=series.series.index[0:1],
name=series._series.name,
index=series._series.index[0:1],
implementation=self._implementation,
),
implementation=self._implementation,
Expand Down
Loading

0 comments on commit 5df15be

Please sign in to comment.