Skip to content

Commit

Permalink
feat: Deprecate Expr.arg_true (but keep Series.arg_true, and keep bot…
Browse files Browse the repository at this point in the history
…h available in stable.v1) (#1827)
  • Loading branch information
MarcoGorelli authored Jan 20, 2025
1 parent c676b68 commit d9a04c0
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 51 deletions.
49 changes: 6 additions & 43 deletions narwhals/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2206,50 +2206,13 @@ def arg_true(self) -> Self:
Returns:
A new expression.
Examples:
>>> import pandas as pd
>>> import polars as pl
>>> import pyarrow as pa
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>>
>>> data = {"a": [1, None, None, 2]}
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)
>>> df_pa = pa.table(data)
We define a library agnostic function:
>>> def agnostic_arg_true(df_native: IntoFrameT) -> IntoFrameT:
... df = nw.from_native(df_native)
... return df.select(nw.col("a").is_null().arg_true()).to_native()
We can then pass any supported library such as pandas, Polars, or
PyArrow to `agnostic_arg_true`:
>>> agnostic_arg_true(df_pd)
a
1 1
2 2
>>> agnostic_arg_true(df_pl)
shape: (2, 1)
┌─────┐
│ a │
│ --- │
│ u32 │
╞═════╡
│ 1 │
│ 2 │
└─────┘
>>> agnostic_arg_true(df_pa)
pyarrow.Table
a: int64
----
a: [[1,2]]
"""
msg = (
"`Expr.arg_true` is deprecated and will be removed in a future version.\n\n"
"Note: this will remain available in `narwhals.stable.v1`.\n"
"See https://narwhals-dev.github.io/narwhals/backcompat/ for more information.\n"
)
issue_deprecation_warning(msg, _version="1.23.0")
return self.__class__(
lambda plx: self._to_compliant_expr(plx).arg_true(), is_order_dependent=True
)
Expand Down
10 changes: 10 additions & 0 deletions narwhals/stable/v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,16 @@ def sort(self, *, descending: bool = False, nulls_last: bool = False) -> Self:
is_order_dependent=True,
)

def arg_true(self) -> Self:
"""Find elements where boolean expression is True.
Returns:
A new expression.
"""
return self.__class__(
lambda plx: self._to_compliant_expr(plx).arg_true(), is_order_dependent=True
)

def sample(
self: Self,
n: int | None = None,
Expand Down
16 changes: 8 additions & 8 deletions tests/expr_and_series/arg_true_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

import pytest

import narwhals.stable.v1 as nw
import narwhals as nw
import narwhals.stable.v1 as nw_v1
from tests.utils import ConstructorEager
from tests.utils import assert_equal_data


def test_arg_true(
constructor_eager: ConstructorEager, request: pytest.FixtureRequest
) -> None:
if "dask" in str(constructor_eager):
request.applymarker(pytest.mark.xfail)
df = nw.from_native(constructor_eager({"a": [1, None, None, 3]}))
result = df.select(nw.col("a").is_null().arg_true())
def test_arg_true(constructor_eager: ConstructorEager) -> None:
df = nw_v1.from_native(constructor_eager({"a": [1, None, None, 3]}))
result = df.select(nw_v1.col("a").is_null().arg_true())
expected = {"a": [1, 2]}
assert_equal_data(result, expected)

with pytest.deprecated_call():
df.select(nw.col("a").is_null().arg_true())


def test_arg_true_series(constructor_eager: ConstructorEager) -> None:
df = nw.from_native(constructor_eager({"a": [1, None, None, 3]}), eager_only=True)
Expand Down

0 comments on commit d9a04c0

Please sign in to comment.