-
Notifications
You must be signed in to change notification settings - Fork 170
feat: Adds {Expr,Series}.{first,last}
#2528
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
Merged
Merged
Changes from 23 commits
Commits
Show all changes
156 commits
Select commit
Hold shift + click to select a range
ff661ae
chore: Add `CompliantExpr.first`
dangotbanned 1b77bd7
feat: "Implement" `PolarsExpr.First`
dangotbanned e84cba3
feat: Add `EagerExpr.first`
dangotbanned 25ef241
chore: Repeat for `*Series`
dangotbanned 78822aa
feat: Add `(Arrow|PandasLike)Series.first()`
dangotbanned 4075c50
chore: Mark `LazyExpr.first` as `not_implemented` for now
dangotbanned 45f24b9
feat: Add `SparkLikeExpr.first`
dangotbanned 4041dd1
feat: Add `DuckDBExpr.first`
dangotbanned bb9912d
feat: Add `DaskExpr.first`
dangotbanned 6a53aa1
revert: 4075c50f2496ab9908b25dc15e240650bc686dc0
dangotbanned 4efc939
feat: Add `nw.Series.first`
dangotbanned fc149c1
test: Add `Series.first` tests
dangotbanned 7489e61
fix: I guess the stubs were wrong then?
dangotbanned d2719a4
fix: Handle the out-of-bounds case
dangotbanned 0af11db
fix: `polars` backcompat
dangotbanned afe20f0
docs: Add `Series.first`
dangotbanned 6c0bd6f
lol version typo
dangotbanned e0fdf78
cov
dangotbanned aa7c510
chore: Add `nw.Expr.first`
dangotbanned 4fdc0aa
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned bd4ab89
feat: Maybe `SparkLike` requires `order_by`?
dangotbanned 9f7f5a9
test: Try out eager backends
dangotbanned ddb50d2
Merge branch 'main' into expr-first
dangotbanned 7146f60
test: Add mostly broken lazy tests π’
dangotbanned 8c24e6e
feat: `duckdb` support?
dangotbanned 54a4cb4
test: Update xfails
dangotbanned 63e0459
fix: Use `head(1)` in `DaskExpr`
dangotbanned 9493aad
ignore cov
dangotbanned 88535a4
Apply suggestion
dangotbanned 77ae9c0
test: Remove dask `xfail`
dangotbanned c1a6173
revert: Remove `dask` implementation
dangotbanned 3c4ff9b
refactor(typing): Use `PythonLiteral` for `Series` return
dangotbanned 696e35d
Merge branch 'main' into expr-first
dangotbanned b2866d2
Merge branch 'main' into expr-first
dangotbanned cd002f3
test: Add `test_group_by_agg_first`
dangotbanned 1458530
feat(DRAFT): Start trying `pyarrow` `agg(first())`
dangotbanned 962ebcd
fix: Maybe `pyarrow` support?
dangotbanned 5d310bc
refactor: Add `ArrowGroupBy._configure_agg`
dangotbanned a417341
fix: Add `pyarrow` compat for `first`
dangotbanned 354da1a
fix: Don't support below `14` ever
dangotbanned 0cea41b
test: Add some `None` cases
dangotbanned 5229096
feat(DRAFT): Partial support for `pandas`
dangotbanned 8d3aaec
docs: Tidy error and comments
dangotbanned a62e3ef
Merge branch 'main' into expr-first
dangotbanned 9c36285
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned ad8e3f7
test: xfail `ibis`
dangotbanned 628f71e
feat: Add `IbisExpr.first`
dangotbanned deacc71
test: Don't xfail for `pandas<1.0.0`
dangotbanned 5c52ee4
Merge branch 'main' into expr-first
dangotbanned eec2a4f
Merge branch 'main' into expr-first
dangotbanned e003bab
Merge branch 'main' into expr-first
dangotbanned fb2dc1c
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 211673b
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 652615f
fix: Use reverted `partition_by`, `_sort`
dangotbanned 68fdfe8
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned ecaca9a
fix: Update `DuckDBExpr.first`
dangotbanned ea30f26
fix: Update `IbisExpr.first`
dangotbanned 12987ee
fix: Update `SparkLikeExpr.first`
dangotbanned 7d70a42
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 5446095
test: Update `pandas` xfail
dangotbanned b927340
Merge branch 'main' into expr-first
dangotbanned f62c085
test: Don't xfail for pandas `1.1.3<=...<1.1.5`
dangotbanned 45d20c8
Merge branch 'main' into expr-first
dangotbanned 72ab185
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned e72b115
fix: Upgrade `DuckDBExpr.first` again
dangotbanned fae137c
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned cb363be
test(DRAFT): Let's start trying to fix pandas
dangotbanned bc80a5f
try `pandas>=2.2.1` path
dangotbanned 14051fa
allow very old pandas that worked?
dangotbanned 3d42dcf
test: xfail `pandas[pyarrow]`, `modin[pyarrow]`
dangotbanned 934d09e
Apply suggestion narwhals/_polars/series.py
dangotbanned 3fbf6f2
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 801a7a8
docs: Be more explicit on WIP `pandas`
dangotbanned 47bfaba
docs: Link to long explanation
dangotbanned 4618d01
revert: remove lazy support
dangotbanned 1998ad2
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 570cdaf
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned d561027
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned b77d2b3
try `nth` for `>=1.1.5; <2.0.0`
dangotbanned 2b0bc16
Is this fixed?
dangotbanned abbb4b7
cov
dangotbanned ccfe532
feat: Add `(Expr|Series).last`
dangotbanned dd1f89e
test: Add `last_test.py`
dangotbanned 54b3188
test: Add `test_group_by_agg_last`
dangotbanned 5f9ff6f
fix: Add missing `PandasLikeGroupBy._REMAP_AGGS` entry
dangotbanned 4000b25
test: Repeat `@single_cases` pattern for `first`
dangotbanned 1c62ce2
docs: Examples for `Expr.(first|last)`
dangotbanned 64fdf10
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 063e5d0
Remove `modin` todo
dangotbanned 2e4f260
Merge branch 'main' into expr-first
dangotbanned 65e6804
clean up and doc `pandas`
dangotbanned 22fae20
feat: Warn on new pandas apply path
dangotbanned 60624b9
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned d66fddc
cov
dangotbanned 5e444a5
always use `apply` for `cudf` π’
dangotbanned e1a9bc3
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 0cbe33d
Merge branch 'main' into expr-first
dangotbanned 2960736
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 4ede6b2
merge main
FBruzzesi 2ae4245
special path for orderable_aggregation in over
FBruzzesi b8066c4
expand on comments
FBruzzesi 2dae6ef
assign metadata in arrow
FBruzzesi 3aa52dc
Merge branch 'main' into expr-first
FBruzzesi 7c578c7
Merge branch 'main' into expr-first
dangotbanned 30bad0e
Merge branch 'main' into expr-first
dangotbanned d269d56
Merge branch 'main' into expr-first
dangotbanned c0e37aa
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 6f5c05b
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 20be193
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned abd027a
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 1fd9fd3
Merge branch 'main' into expr-first
dangotbanned 94d6b19
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 849a6d9
Merge branch 'main' into expr-first
dangotbanned 476c63e
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned c169104
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned d77fcd1
Merge branch 'main' into expr-first
dangotbanned 1f38bde
Merge branch 'main' into expr-first
dangotbanned 3c63726
Merge branch 'main' into expr-first
dangotbanned 6d7b09b
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 3b6301f
Merge branch 'main' into expr-first
dangotbanned bfc55c7
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned f47ef14
docs: Remove *Returns* from `Expr` version
dangotbanned b32db75
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned f22a497
Merge branch 'main' into expr-first
dangotbanned b5fe1ba
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 0f301e7
Merge branch 'main' into expr-first
dangotbanned 16a2762
Merge branch 'main' into expr-first
dangotbanned 09dca76
Merge branch 'main' into expr-first
dangotbanned ffe7e24
Merge remote-tracking branch 'upstream/main' into expr-first
dangotbanned 0fb0455
chore(typing): fix incompatible override
dangotbanned 6d63ea6
simplify grouped first/last#
MarcoGorelli 7b00310
simplify test, remove unnecessary over(order_by)
MarcoGorelli 016abc9
combine tests
MarcoGorelli 29d6cb7
combine tests
MarcoGorelli 3b91e23
duckdb fix#
MarcoGorelli c87935d
sort out ibis
MarcoGorelli 0393dfe
dask
MarcoGorelli 466c922
add note to docs
MarcoGorelli 4266e4b
remove unnecessary code
MarcoGorelli 555098b
pyarrow
MarcoGorelli 36e38e0
fixup
MarcoGorelli 42d2cd6
typing
MarcoGorelli 63f012a
dask
MarcoGorelli c4ac043
test and support `diff().sum().over(order_by=...)`
MarcoGorelli 8739b6a
cross-pandas version compat
MarcoGorelli ff22604
make test more unusual
MarcoGorelli d9c4a1b
fix another pyarrow issue
MarcoGorelli 03b7969
catch more warnings for modin
MarcoGorelli d01a398
factor out sql_expression, link to feature request
MarcoGorelli 18c0861
combine first and last blocks
MarcoGorelli 948d96d
remove more unneeded
MarcoGorelli 8810d03
less special-casing
MarcoGorelli 843549f
simplify further
MarcoGorelli d7be792
Merge remote-tracking branch 'upstream/main' into expr-first
MarcoGorelli 363490d
typing
MarcoGorelli c25d649
use repeat_by instead of lit for polars
MarcoGorelli File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,7 @@ | |
| - ewm_mean | ||
| - fill_null | ||
| - filter | ||
| - first | ||
| - gather_every | ||
| - head | ||
| - clip | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,6 +28,7 @@ | |
| - ewm_mean | ||
| - fill_null | ||
| - filter | ||
| - first | ||
| - gather_every | ||
| - head | ||
| - hist | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -801,6 +801,25 @@ def clip( | |
| ) | ||
| ) | ||
|
|
||
| def first(self) -> Any: | ||
| """Get the first element of the Series. | ||
|
|
||
| Returns: | ||
| A scalar value or `None` if the Series is empty. | ||
|
|
||
| Examples: | ||
| >>> import polars as pl | ||
| >>> import narwhals as nw | ||
| >>> | ||
| >>> s_native = pl.Series([1, 2, 3]) | ||
| >>> s_nw = nw.from_native(s_native, series_only=True) | ||
| >>> s_nw.first() | ||
| 1 | ||
| >>> s_nw.filter(s_nw > 5).first() is None | ||
| True | ||
|
Comment on lines
+900
to
+909
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like the I think it's important to have an example for that case though - since |
||
| """ | ||
| return self._compliant_series.first() | ||
|
|
||
| def is_in(self, other: Any) -> Self: | ||
| """Check if the elements of this Series are in the other sequence. | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| from __future__ import annotations | ||
|
|
||
| from typing import TYPE_CHECKING | ||
| from typing import Mapping | ||
| from typing import Sequence | ||
|
|
||
| import pytest | ||
|
|
||
| import narwhals as nw | ||
| from tests.utils import assert_equal_data | ||
|
|
||
| if TYPE_CHECKING: | ||
| from narwhals.typing import PythonLiteral | ||
| from tests.utils import ConstructorEager | ||
|
|
||
| data = { | ||
| "a": [8, 2, 1, None], | ||
| "b": [58, 5, 6, 12], | ||
| "c": [2.5, 1.0, 3.0, 0.9], | ||
| "d": [2, 1, 4, 3], | ||
| } | ||
|
|
||
|
|
||
| @pytest.mark.parametrize(("col", "expected"), [("a", 8), ("b", 58), ("c", 2.5)]) | ||
| def test_first_series( | ||
| constructor_eager: ConstructorEager, col: str, expected: PythonLiteral | ||
| ) -> None: | ||
| series = nw.from_native(constructor_eager(data), eager_only=True)[col] | ||
| result = series.first() | ||
| assert_equal_data({col: [result]}, {col: [expected]}) | ||
|
|
||
|
|
||
| def test_first_series_empty(constructor_eager: ConstructorEager) -> None: | ||
| series = nw.from_native(constructor_eager(data), eager_only=True)["a"] | ||
| series = series.filter(series > 50) | ||
| result = series.first() | ||
| assert result is None | ||
|
|
||
|
|
||
| @pytest.mark.parametrize(("col", "expected"), [("a", 8), ("b", 58), ("c", 2.5)]) | ||
| def test_first_expr_eager( | ||
| constructor_eager: ConstructorEager, col: str, expected: PythonLiteral | ||
| ) -> None: | ||
| df = nw.from_native(constructor_eager(data)) | ||
| expr = nw.col(col).first() | ||
| result = df.select(expr) | ||
| assert_equal_data(result, {col: [expected]}) | ||
dangotbanned marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "expected", | ||
| [{"a": [8], "c": [2.5]}, {"d": [2], "b": [58]}, {"c": [2.5], "a": [8], "d": [2]}], | ||
| ) | ||
| def test_first_expr_eager_expand( | ||
| constructor_eager: ConstructorEager, expected: Mapping[str, Sequence[PythonLiteral]] | ||
| ) -> None: | ||
| df = nw.from_native(constructor_eager(data)) | ||
| expr = nw.col(expected).first() | ||
| result = df.select(expr) | ||
| assert_equal_data(result, expected) | ||
|
|
||
|
|
||
| def test_first_expr_eager_expand_sort(constructor_eager: ConstructorEager) -> None: | ||
| df = nw.from_native(constructor_eager(data)) | ||
| expr = nw.col("d", "a", "b", "c").first() | ||
| result = df.sort("d").select(expr) | ||
| expected = {"d": [1], "a": [2], "b": [5], "c": [1.0]} | ||
| assert_equal_data(result, expected) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.