Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: rename changes_length to filtration #2094

Merged
merged 1 commit into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions narwhals/_expression_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,8 @@ class ExprKind(Enum):

Commutative composition rules are:
- LITERAL vs LITERAL -> LITERAL
- CHANGES_LENGTH vs (LITERAL | AGGREGATION) -> CHANGES_LENGTH
- CHANGES_LENGTH vs (CHANGES_LENGTH | TRANSFORM | WINDOW) -> raise
- FILTRATION vs (LITERAL | AGGREGATION) -> FILTRATION
- FILTRATION vs (FILTRATION | TRANSFORM | WINDOW) -> raise
- (TRANSFORM | WINDOW) vs (LITERAL | AGGREGATION) -> TRANSFORM
- AGGREGATION vs (LITERAL | AGGREGATION) -> AGGREGATION
"""
Expand All @@ -358,7 +358,7 @@ class ExprKind(Enum):
- `nw.col('a').cum_sum().mean()`
"""

CHANGES_LENGTH = auto()
FILTRATION = auto()
"""e.g. `nw.col('a').drop_nulls()`"""

def preserves_length(self) -> bool:
Expand All @@ -367,8 +367,8 @@ def preserves_length(self) -> bool:
def is_window(self) -> bool:
return self is ExprKind.WINDOW

def is_changes_length(self) -> bool:
return self is ExprKind.CHANGES_LENGTH
def is_filtration(self) -> bool:
return self is ExprKind.FILTRATION

def is_scalar_like(self) -> bool:
return is_scalar_like(self)
Expand Down Expand Up @@ -420,7 +420,7 @@ def selector() -> ExprMetadata:
def combine_metadata(*args: IntoExpr | object | None, str_as_lit: bool) -> ExprMetadata:
# Combine metadata from `args`.

n_changes_length = 0
n_filtrations = 0
has_transforms_or_windows = False
has_aggregations = False
has_literals = False
Expand All @@ -437,8 +437,8 @@ def combine_metadata(*args: IntoExpr | object | None, str_as_lit: bool) -> ExprM
has_aggregations = True
elif kind is ExprKind.LITERAL:
has_literals = True
elif kind is ExprKind.CHANGES_LENGTH:
n_changes_length += 1
elif kind is ExprKind.FILTRATION:
n_filtrations += 1
elif kind.preserves_length():
has_transforms_or_windows = True
else: # pragma: no cover
Expand All @@ -448,17 +448,17 @@ def combine_metadata(*args: IntoExpr | object | None, str_as_lit: bool) -> ExprM
has_literals
and not has_aggregations
and not has_transforms_or_windows
and not n_changes_length
and not n_filtrations
):
result_kind = ExprKind.LITERAL
elif n_changes_length > 1:
elif n_filtrations > 1:
msg = "Length-changing expressions can only be used in isolation, or followed by an aggregation"
raise LengthChangingExprError(msg)
elif n_changes_length and has_transforms_or_windows:
elif n_filtrations and has_transforms_or_windows:
msg = "Cannot combine length-changing expressions with length-preserving ones or aggregations"
raise ShapeError(msg)
elif n_changes_length:
result_kind = ExprKind.CHANGES_LENGTH
elif n_filtrations:
result_kind = ExprKind.FILTRATION
elif has_transforms_or_windows:
result_kind = ExprKind.TRANSFORM
else:
Expand Down
2 changes: 1 addition & 1 deletion narwhals/dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -2212,7 +2212,7 @@ def _extract_compliant(self: Self, arg: Any) -> Any:
" `over` and they will be supported."
)
raise OrderDependentExprError(msg)
if arg._metadata.kind.is_changes_length():
if arg._metadata.kind.is_filtration():
msg = (
"Length-changing expressions are not supported for use in LazyFrame, unless\n"
"followed by an aggregation.\n\n"
Expand Down
22 changes: 11 additions & 11 deletions narwhals/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ def map_batches(
function=function, return_dtype=return_dtype
),
# safest assumptions
self._metadata.with_kind_and_extra_open_window(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind_and_extra_open_window(ExprKind.FILTRATION),
)

def skew(self: Self) -> Self:
Expand Down Expand Up @@ -869,7 +869,7 @@ def unique(self: Self) -> Self:
"""
return self.__class__(
lambda plx: self._to_compliant_expr(plx).unique(),
self._metadata.with_kind(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind(ExprKind.FILTRATION),
)

def abs(self: Self) -> Self:
Expand Down Expand Up @@ -1233,7 +1233,7 @@ def filter(self: Self, *predicates: Any) -> Self:
str_as_lit=False,
),
combine_metadata(self, *flat_predicates, str_as_lit=False).with_kind(
ExprKind.CHANGES_LENGTH
ExprKind.FILTRATION
),
)

Expand Down Expand Up @@ -1321,7 +1321,7 @@ def arg_true(self: Self) -> Self:
issue_deprecation_warning(msg, _version="1.23.0")
return self.__class__(
lambda plx: self._to_compliant_expr(plx).arg_true(),
self._metadata.with_kind_and_extra_open_window(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind_and_extra_open_window(ExprKind.FILTRATION),
)

def fill_null(
Expand Down Expand Up @@ -1449,7 +1449,7 @@ def drop_nulls(self: Self) -> Self:
"""
return self.__class__(
lambda plx: self._to_compliant_expr(plx).drop_nulls(),
self._metadata.with_kind(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind(ExprKind.FILTRATION),
)

def sample(
Expand Down Expand Up @@ -1490,7 +1490,7 @@ def sample(
lambda plx: self._to_compliant_expr(plx).sample(
n, fraction=fraction, with_replacement=with_replacement, seed=seed
),
self._metadata.with_kind(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind(ExprKind.FILTRATION),
)

def over(
Expand Down Expand Up @@ -1535,7 +1535,7 @@ def over(
|2 4 y 4|
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
"""
if self._metadata.kind.is_changes_length():
if self._metadata.kind.is_filtration():
msg = "`.over()` can not be used for expressions which change length."
raise LengthChangingExprError(msg)
kind = ExprKind.TRANSFORM
Expand Down Expand Up @@ -1754,7 +1754,7 @@ def head(self: Self, n: int = 10) -> Self:
issue_deprecation_warning(msg, _version="1.22.0")
return self.__class__(
lambda plx: self._to_compliant_expr(plx).head(n),
self._metadata.with_kind_and_extra_open_window(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind_and_extra_open_window(ExprKind.FILTRATION),
)

def tail(self: Self, n: int = 10) -> Self:
Expand Down Expand Up @@ -1782,7 +1782,7 @@ def tail(self: Self, n: int = 10) -> Self:
issue_deprecation_warning(msg, _version="1.22.0")
return self.__class__(
lambda plx: self._to_compliant_expr(plx).tail(n),
self._metadata.with_kind_and_extra_open_window(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind_and_extra_open_window(ExprKind.FILTRATION),
)

def round(self: Self, decimals: int = 0) -> Self:
Expand Down Expand Up @@ -1877,7 +1877,7 @@ def gather_every(self: Self, n: int, offset: int = 0) -> Self:
issue_deprecation_warning(msg, _version="1.22.0")
return self.__class__(
lambda plx: self._to_compliant_expr(plx).gather_every(n=n, offset=offset),
self._metadata.with_kind_and_extra_open_window(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind_and_extra_open_window(ExprKind.FILTRATION),
)

# need to allow numeric typing
Expand Down Expand Up @@ -1949,7 +1949,7 @@ def mode(self: Self) -> Self:
"""
return self.__class__(
lambda plx: self._to_compliant_expr(plx).mode(),
self._metadata.with_kind(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind(ExprKind.FILTRATION),
)

def is_finite(self: Self) -> Self:
Expand Down
2 changes: 1 addition & 1 deletion narwhals/expr_cat.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,5 @@ def get_categories(self: Self) -> ExprT:
"""
return self._expr.__class__(
lambda plx: self._expr._to_compliant_expr(plx).cat.get_categories(),
self._expr._metadata.with_kind(ExprKind.CHANGES_LENGTH),
self._expr._metadata.with_kind(ExprKind.FILTRATION),
)
14 changes: 7 additions & 7 deletions narwhals/stable/v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ def _extract_compliant(self: Self, arg: Any) -> Any:
msg = "Mixing Series with LazyFrame is not supported."
raise TypeError(msg)
if isinstance(arg, Expr):
# After stable.v1, we raise if arg._is_order_dependent or arg._changes_length
# After stable.v1, we raise for order-dependent exprs or filtrations
return arg._to_compliant_expr(self.__narwhals_namespace__())
if isinstance(arg, str):
plx = self.__narwhals_namespace__()
Expand Down Expand Up @@ -968,7 +968,7 @@ def head(self: Self, n: int = 10) -> Self:
"""
return self.__class__(
lambda plx: self._to_compliant_expr(plx).head(n),
self._metadata.with_kind_and_extra_open_window(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind_and_extra_open_window(ExprKind.FILTRATION),
)

def tail(self: Self, n: int = 10) -> Self:
Expand All @@ -982,7 +982,7 @@ def tail(self: Self, n: int = 10) -> Self:
"""
return self.__class__(
lambda plx: self._to_compliant_expr(plx).tail(n),
self._metadata.with_kind_and_extra_open_window(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind_and_extra_open_window(ExprKind.FILTRATION),
)

def gather_every(self: Self, n: int, offset: int = 0) -> Self:
Expand All @@ -997,7 +997,7 @@ def gather_every(self: Self, n: int, offset: int = 0) -> Self:
"""
return self.__class__(
lambda plx: self._to_compliant_expr(plx).gather_every(n=n, offset=offset),
self._metadata.with_kind_and_extra_open_window(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind_and_extra_open_window(ExprKind.FILTRATION),
)

def unique(self: Self, *, maintain_order: bool | None = None) -> Self:
Expand All @@ -1019,7 +1019,7 @@ def unique(self: Self, *, maintain_order: bool | None = None) -> Self:
warn(message=msg, category=UserWarning, stacklevel=find_stacklevel())
return self.__class__(
lambda plx: self._to_compliant_expr(plx).unique(),
self._metadata.with_kind(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind(ExprKind.FILTRATION),
)

def sort(self: Self, *, descending: bool = False, nulls_last: bool = False) -> Self:
Expand Down Expand Up @@ -1047,7 +1047,7 @@ def arg_true(self: Self) -> Self:
"""
return self.__class__(
lambda plx: self._to_compliant_expr(plx).arg_true(),
self._metadata.with_kind_and_extra_open_window(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind_and_extra_open_window(ExprKind.FILTRATION),
)

def sample(
Expand Down Expand Up @@ -1081,7 +1081,7 @@ def sample(
lambda plx: self._to_compliant_expr(plx).sample(
n, fraction=fraction, with_replacement=with_replacement, seed=seed
),
self._metadata.with_kind(ExprKind.CHANGES_LENGTH),
self._metadata.with_kind(ExprKind.FILTRATION),
)


Expand Down
2 changes: 1 addition & 1 deletion tests/frame/select_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def test_alias_invalid(constructor: Constructor) -> None:
df.lazy().select(nw.all().alias("c")).collect()


def test_changes_length_vs_aggregation(constructor_eager: ConstructorEager) -> None:
def test_filtration_vs_aggregation(constructor_eager: ConstructorEager) -> None:
df = nw.from_native(constructor_eager({"a": [1, None, 3]}))
result = df.select(nw.col("a").drop_nulls(), b=nw.col("a").mean())
expected: dict[str, Any] = {"a": [1, 3], "b": [2.0, 2.0]}
Expand Down
Loading