Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
639ab0a
Implement Expr.single()
dsprenkels Oct 14, 2025
cac7f2c
Implement List.single() and add some tests
dsprenkels Oct 15, 2025
755f0c3
Add a testing for Expr.single
dsprenkels Oct 15, 2025
9975284
Some small polishing
dsprenkels Oct 15, 2025
8da2fe6
Remove List.single() and use agg(F.element().single())
dsprenkels Oct 15, 2025
576546d
Not sure why this doctest failed; does it work now?
dsprenkels Oct 15, 2025
be0bb14
Update dsl-schema-hashes
dsprenkels Oct 15, 2025
65f9c28
Update update_groups_while_evicting
dsprenkels Oct 15, 2025
0dfbfb5
Enable struct for the two error tests
dsprenkels Oct 15, 2025
992c60c
Set IRAggExpr::Single to not observe order
dsprenkels Oct 16, 2025
4f53cb0
single: Add more tests
dsprenkels Oct 16, 2025
0c45359
Deprecate {DataFrame,Series}.item() in favor of .single()
dsprenkels Oct 16, 2025
6f1da8c
Replace .item() with .single() in tests
dsprenkels Oct 16, 2025
dba171b
Revert "Replace .item() with .single() in tests"
dsprenkels Oct 16, 2025
414c3d6
Revert "Deprecate {DataFrame,Series}.item() in favor of .single()"
dsprenkels Oct 16, 2025
e029504
Rename .single() to .item()
dsprenkels Oct 16, 2025
64180dc
Fix some straggler tests
dsprenkels Oct 20, 2025
4024d6a
Merge remote-tracking branch 'upstream/main' into issue-8689_single
dsprenkels Oct 20, 2025
7c349b9
Add "See Also" (get) sections to item() docs
dsprenkels Oct 20, 2025
43f84a9
Update DSL schema hashes
dsprenkels Oct 20, 2025
8c27aa8
Update 2 small comments
dsprenkels Oct 20, 2025
43ed4af
tiny tweak
dsprenkels Oct 20, 2025
6336316
Fix PR comments
dsprenkels Oct 20, 2025
a12276c
Forgot to update one Error construction
dsprenkels Oct 20, 2025
2d0f941
PR comment
dsprenkels Oct 20, 2025
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
3 changes: 3 additions & 0 deletions crates/polars-core/src/frame/group_by/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -875,6 +875,7 @@ pub enum GroupByMethod {
Mean,
First,
Last,
Item,
Sum,
Groups,
NUnique,
Expand All @@ -897,6 +898,7 @@ impl Display for GroupByMethod {
Mean => "mean",
First => "first",
Last => "last",
Item => "item",
Sum => "sum",
Groups => "groups",
NUnique => "n_unique",
Expand All @@ -922,6 +924,7 @@ pub fn fmt_group_by_column(name: &str, method: GroupByMethod) -> PlSmallStr {
Mean => format_pl_smallstr!("{name}_mean"),
First => format_pl_smallstr!("{name}_first"),
Last => format_pl_smallstr!("{name}_last"),
Item => format_pl_smallstr!("{name}_item"),
Sum => format_pl_smallstr!("{name}_sum"),
Groups => PlSmallStr::from_static("groups"),
NUnique => format_pl_smallstr!("{name}_n_unique"),
Expand Down
13 changes: 13 additions & 0 deletions crates/polars-error/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,19 @@ on startup."#.trim_start())
ComputeError: "`strptime` / `to_datetime` was called with no format and no time zone, but a time zone is part of the data.\n\nThis was previously allowed but led to unpredictable and erroneous results. Give a format string, set a time zone or perform the operation eagerly on a Series instead of on an Expr."
)
};
(item_agg_count_not_one = $n:expr) => {
if $n == 0 {
polars_err!(ComputeError:
"aggregation 'item' expected a single value, got none"
)
} else if $n > 1 {
polars_err!(ComputeError:
"aggregation 'item' expected a single value, got {} values", $n
)
} else {
unreachable!()
}
};
}

#[macro_export]
Expand Down
17 changes: 17 additions & 0 deletions crates/polars-expr/src/expressions/aggregation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ impl PhysicalExpr for AggregationExpr {
} else {
s.tail(Some(1))
}),
GroupByMethod::Item => Ok(match s.len() {
1 => s,
n => polars_bail!(item_agg_count_not_one = n),
}),
GroupByMethod::Sum => parallel_op_columns(
|s| s.sum_reduce().map(|sc| sc.into_column(s.name().clone())),
s,
Expand Down Expand Up @@ -332,6 +336,19 @@ impl PhysicalExpr for AggregationExpr {
let agg_s = s.agg_last(&groups);
AggregatedScalar(agg_s.with_name(keep_name))
},
GroupByMethod::Item => {
let (s, groups) = ac.get_final_aggregation();
for gc in groups.group_count().iter() {
match gc {
None | Some(1) => continue,
Some(n) => {
polars_bail!(item_agg_count_not_one = n);
},
}
}
let agg_s = s.agg_first(&groups);
AggregatedScalar(agg_s.with_name(keep_name))
},
GroupByMethod::NUnique => {
let (s, groups) = ac.get_final_aggregation();
let agg_s = s.agg_n_unique(&groups);
Expand Down
1 change: 1 addition & 0 deletions crates/polars-expr/src/planner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ fn create_physical_expr_inner(
I::NUnique(_) => GBM::NUnique,
I::First(_) => GBM::First,
I::Last(_) => GBM::Last,
I::Item(_) => GBM::Item,
I::Mean(_) => GBM::Mean,
I::Implode(_) => GBM::Implode,
I::Quantile { .. } => unreachable!(),
Expand Down
3 changes: 2 additions & 1 deletion crates/polars-expr/src/reduce/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::reduce::bitwise::{
new_bitwise_and_reduction, new_bitwise_or_reduction, new_bitwise_xor_reduction,
};
use crate::reduce::count::{CountReduce, NullCountReduce};
use crate::reduce::first_last::{new_first_reduction, new_last_reduction};
use crate::reduce::first_last::{new_first_reduction, new_item_reduction, new_last_reduction};
use crate::reduce::len::LenReduce;
use crate::reduce::mean::new_mean_reduction;
use crate::reduce::min_max::{new_max_reduction, new_min_reduction};
Expand Down Expand Up @@ -51,6 +51,7 @@ pub fn into_reduction(
},
IRAggExpr::First(input) => (new_first_reduction(get_dt(*input)?), *input),
IRAggExpr::Last(input) => (new_last_reduction(get_dt(*input)?), *input),
IRAggExpr::Item(input) => (new_item_reduction(get_dt(*input)?), *input),
IRAggExpr::Count {
input,
include_nulls,
Expand Down
Loading
Loading