From bca38dbc4ad2d45f92e92211b4309f33d8d04922 Mon Sep 17 00:00:00 2001 From: Stijn de Gooijer Date: Tue, 23 Jan 2024 09:22:09 +0100 Subject: [PATCH 1/3] Fix struct is not null --- crates/polars-core/src/series/implementations/struct_.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/polars-core/src/series/implementations/struct_.rs b/crates/polars-core/src/series/implementations/struct_.rs index 16d758fd5257..1e5298a15074 100644 --- a/crates/polars-core/src/series/implementations/struct_.rs +++ b/crates/polars-core/src/series/implementations/struct_.rs @@ -304,7 +304,7 @@ impl SeriesTrait for SeriesWrap { /// Get a mask of the non-null values. fn is_not_null(&self) -> BooleanChunked { let is_not_null = self.0.fields().iter().map(|s| s.is_not_null()); - is_not_null.reduce(|lhs, rhs| lhs.bitand(rhs)).unwrap() + is_not_null.reduce(|lhs, rhs| lhs.bitor(rhs)).unwrap() } fn shrink_to_fit(&mut self) { From 577be9a7a4aa01904b3ca6810d3dcb87b48cb839 Mon Sep 17 00:00:00 2001 From: Stijn de Gooijer Date: Tue, 23 Jan 2024 09:22:13 +0100 Subject: [PATCH 2/3] Add tests --- .../tests/unit/operations/test_is_null.py | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 py-polars/tests/unit/operations/test_is_null.py diff --git a/py-polars/tests/unit/operations/test_is_null.py b/py-polars/tests/unit/operations/test_is_null.py new file mode 100644 index 000000000000..7e1a53fa04c9 --- /dev/null +++ b/py-polars/tests/unit/operations/test_is_null.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +from hypothesis import given + +import polars as pl +from polars.testing import assert_frame_equal, assert_series_equal +from polars.testing.parametric import series + + +@given(s=series(null_probability=0.5)) +def test_is_null_parametric(s: pl.Series) -> None: + is_null = s.is_null() + is_not_null = s.is_not_null() + + assert is_null.null_count() == 0 + assert_series_equal(is_null, ~is_not_null) + + +def test_is_null_struct() -> None: + df = pl.DataFrame( + { + "x": [ + {"a": 1, "b": 2}, + {"a": 1, "b": None}, + {"a": None, "b": 2}, + {"a": None, "b": None}, + ] + } + ) + + result = df.select( + null=pl.col("x").is_null(), + not_null=pl.col("x").is_not_null(), + ) + + expected = pl.DataFrame( + { + "null": [False, False, False, True], + "not_null": [True, True, True, False], + } + ) + assert_frame_equal(result, expected) + + +def test_is_null_null() -> None: + s = pl.Series([None, None]) + + result = s.is_null() + expected = pl.Series([True, True]) + assert_series_equal(result, expected) + + result = s.is_not_null() + expected = pl.Series([False, False]) + assert_series_equal(result, expected) From 2d8b0c244c0b8587513ac5955b1b58dfc089801f Mon Sep 17 00:00:00 2001 From: Stijn de Gooijer Date: Tue, 23 Jan 2024 09:33:06 +0100 Subject: [PATCH 3/3] Add tests for drop nulls --- .../tests/unit/operations/test_drop_nulls.py | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 py-polars/tests/unit/operations/test_drop_nulls.py diff --git a/py-polars/tests/unit/operations/test_drop_nulls.py b/py-polars/tests/unit/operations/test_drop_nulls.py new file mode 100644 index 000000000000..1ca966f8314a --- /dev/null +++ b/py-polars/tests/unit/operations/test_drop_nulls.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from hypothesis import given + +import polars as pl +from polars.testing import assert_frame_equal, assert_series_equal +from polars.testing.parametric import series + + +@given(s=series(null_probability=0.5)) +def test_drop_nulls_parametric(s: pl.Series) -> None: + result = s.drop_nulls() + assert result.len() == s.len() - s.null_count() + + filter_result = s.filter(s.is_not_null()) + assert_series_equal(result, filter_result) + + +def test_df_drop_nulls_struct() -> None: + df = pl.DataFrame( + { + "x": [ + {"a": 1, "b": 2}, + {"a": 1, "b": None}, + {"a": None, "b": 2}, + {"a": None, "b": None}, + ] + } + ) + + result = df.drop_nulls() + + expected = df.head(3) + assert_frame_equal(result, expected)