From 80ece09f0d105fc22a32b35d534c7f2aeb693af9 Mon Sep 17 00:00:00 2001 From: Orson Peters Date: Fri, 6 Sep 2024 18:51:08 +0200 Subject: [PATCH] refactor(rust): Fix nan-ignoring max/min in new-streaming --- crates/polars-core/src/datatypes/any_value.rs | 8 ++++++++ crates/polars-core/src/scalar/mod.rs | 5 +++++ crates/polars-expr/src/reduce/min_max.rs | 8 ++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/crates/polars-core/src/datatypes/any_value.rs b/crates/polars-core/src/datatypes/any_value.rs index 5475b8fb5203..c3f5f57e0c68 100644 --- a/crates/polars-core/src/datatypes/any_value.rs +++ b/crates/polars-core/src/datatypes/any_value.rs @@ -499,6 +499,14 @@ impl<'a> AnyValue<'a> { ) } + pub fn is_nan(&self) -> bool { + match self { + AnyValue::Float32(f) => f.is_nan(), + AnyValue::Float64(f) => f.is_nan(), + _ => false, + } + } + pub fn is_null(&self) -> bool { matches!(self, AnyValue::Null) } diff --git a/crates/polars-core/src/scalar/mod.rs b/crates/polars-core/src/scalar/mod.rs index ed0ab1f98bfa..ac7a946ebebc 100644 --- a/crates/polars-core/src/scalar/mod.rs +++ b/crates/polars-core/src/scalar/mod.rs @@ -22,6 +22,11 @@ impl Scalar { self.value.is_null() } + #[inline(always)] + pub fn is_nan(&self) -> bool { + self.value.is_nan() + } + #[inline(always)] pub fn value(&self) -> &AnyValue<'static> { &self.value diff --git a/crates/polars-expr/src/reduce/min_max.rs b/crates/polars-expr/src/reduce/min_max.rs index 5d514ce218c5..ba011d7d95f0 100644 --- a/crates/polars-expr/src/reduce/min_max.rs +++ b/crates/polars-expr/src/reduce/min_max.rs @@ -25,7 +25,9 @@ struct MinReduceState { impl MinReduceState { fn update_with_value(&mut self, other: &AnyValue<'static>) { - if self.value.is_null() || !other.is_null() && other < self.value.value() { + if self.value.is_null() + || !other.is_null() && (other < self.value.value() || self.value.is_nan()) + { self.value.update(other.clone()); } } @@ -78,7 +80,9 @@ struct MaxReduceState { impl MaxReduceState { fn update_with_value(&mut self, other: &AnyValue<'static>) { - if self.value.is_null() || !other.is_null() && other > self.value.value() { + if self.value.is_null() + || !other.is_null() && (other > self.value.value() || self.value.is_nan()) + { self.value.update(other.clone()); } }