From 1907b35b405d3acfea55f308d6ccfbbb6dd9d6f5 Mon Sep 17 00:00:00 2001 From: 40gilad <40gilad.shenkar@gmail.com> Date: Sun, 8 Sep 2024 13:04:36 +0300 Subject: [PATCH 1/3] fix issue #59712 --- pandas/core/groupby/ops.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pandas/core/groupby/ops.py b/pandas/core/groupby/ops.py index da80969b613cd..8aa715682be19 100644 --- a/pandas/core/groupby/ops.py +++ b/pandas/core/groupby/ops.py @@ -371,14 +371,6 @@ def _call_cython_op( is_datetimelike = dtype.kind in "mM" - if is_datetimelike: - values = values.view("int64") - is_numeric = True - elif dtype.kind == "b": - values = values.view("uint8") - if values.dtype == "float16": - values = values.astype(np.float32) - if self.how in ["any", "all"]: if mask is None: mask = isna(values) @@ -392,6 +384,14 @@ def _call_cython_op( values = values.astype(bool, copy=False).view(np.int8) is_numeric = True + if is_datetimelike: + values = values.view("int64") + is_numeric = True + elif dtype.kind == "b": + values = values.view("uint8") + if values.dtype == "float16": + values = values.astype(np.float32) + values = values.T if mask is not None: mask = mask.T From c5c67ddcc44cd67391a0ddb09f97ca8a0d76c910 Mon Sep 17 00:00:00 2001 From: 40gilad <40gilad.shenkar@gmail.com> Date: Sun, 8 Sep 2024 13:38:39 +0300 Subject: [PATCH 2/3] fix issue #59712 --- pandas/core/groupby/ops.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pandas/core/groupby/ops.py b/pandas/core/groupby/ops.py index 8aa715682be19..703c270132a02 100644 --- a/pandas/core/groupby/ops.py +++ b/pandas/core/groupby/ops.py @@ -371,19 +371,6 @@ def _call_cython_op( is_datetimelike = dtype.kind in "mM" - if self.how in ["any", "all"]: - if mask is None: - mask = isna(values) - if dtype == object: - if kwargs["skipna"]: - # GH#37501: don't raise on pd.NA when skipna=True - if mask.any(): - # mask on original values computed separately - values = values.copy() - values[mask] = True - values = values.astype(bool, copy=False).view(np.int8) - is_numeric = True - if is_datetimelike: values = values.view("int64") is_numeric = True @@ -398,6 +385,19 @@ def _call_cython_op( if result_mask is not None: result_mask = result_mask.T + if self.how in ["any", "all"]: + if mask is None: + mask = isna(values) + if dtype == object: + if kwargs["skipna"]: + # GH#37501: don't raise on pd.NA when skipna=True + if mask.any(): + # mask on original values computed separately + values = values.copy() + values[mask] = True + values = values.astype(bool, copy=False).view(np.int8) + is_numeric = True + out_shape = self._get_output_shape(ngroups, values) func = self._get_cython_function(self.kind, self.how, values.dtype, is_numeric) values = self._get_cython_vals(values) From d69350d9143930ab23d2e32f48a195d286f64a97 Mon Sep 17 00:00:00 2001 From: 40gilad <40gilad.shenkar@gmail.com> Date: Sun, 8 Sep 2024 14:46:47 +0300 Subject: [PATCH 3/3] added test func test_groupby_any_timedelta_with_all_nulls() --- pandas/tests/groupby/test_grouping.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pandas/tests/groupby/test_grouping.py b/pandas/tests/groupby/test_grouping.py index fc2a8a970010a..b1d84f8ac4657 100644 --- a/pandas/tests/groupby/test_grouping.py +++ b/pandas/tests/groupby/test_grouping.py @@ -1180,3 +1180,15 @@ def test_grouping_by_key_is_in_axis(): result = gb.sum() expected = DataFrame({"a": [1, 2], "b": [1, 2], "c": [7, 5]}) tm.assert_frame_equal(result, expected) + +def test_groupby_any_timedelta_with_all_nulls(): + # Create a DataFrame with timedelta values, including NaT (null timedelta) + df = pd.DataFrame({ + 'timedelta': [pd.Timedelta(days=1), pd.NaT], + 'group': [0, 1] + }) + result = df.groupby('group')['timedelta'].any() + + # Expected behavior: group 1 should return False because it has all null values + expected = pd.Series([True, False], index=[0, 1]) + pd.testing.assert_series_equal(result, expected)