diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py index ddb2f01898ec7..7edd2fa585156 100644 --- a/pandas/core/arrays/arrow/array.py +++ b/pandas/core/arrays/arrow/array.py @@ -1032,6 +1032,9 @@ def _reduce(self, name: str, *, skipna: bool = True, **kwargs): not_eq = pc.not_equal(data_to_cmp, 0) data_to_reduce = not_eq + elif name in ["min", "max", "sum"] and pa.types.is_duration(pa_type): + data_to_reduce = self._data.cast(pa.int64()) + if name == "sem": def pyarrow_meth(data, skip_nulls, **kwargs): @@ -1066,6 +1069,9 @@ def pyarrow_meth(data, skip_nulls, **kwargs): raise TypeError(msg) from err if pc.is_null(result).as_py(): return self.dtype.na_value + + if name in ["min", "max", "sum"] and pa.types.is_duration(pa_type): + result = result.cast(pa_type) return result.as_py() def __setitem__(self, key, value) -> None: diff --git a/pandas/tests/extension/base/groupby.py b/pandas/tests/extension/base/groupby.py index 3a9dbe9dfb384..200a494997116 100644 --- a/pandas/tests/extension/base/groupby.py +++ b/pandas/tests/extension/base/groupby.py @@ -137,6 +137,7 @@ def test_in_numeric_groupby(self, data_for_grouping): or is_string_dtype(dtype) or is_period_dtype(dtype) or is_object_dtype(dtype) + or dtype.kind == "m" # in particular duration[*][pyarrow] ): expected = pd.Index(["B", "C"]) result = df.groupby("A").sum().columns diff --git a/pandas/tests/extension/test_arrow.py b/pandas/tests/extension/test_arrow.py index af3952a532113..71fc7e17bf808 100644 --- a/pandas/tests/extension/test_arrow.py +++ b/pandas/tests/extension/test_arrow.py @@ -539,10 +539,6 @@ def test_reduce_series(self, data, all_numeric_reductions, skipna, request): "sem", ] and pa.types.is_temporal(pa_dtype): request.node.add_marker(xfail_mark) - elif all_numeric_reductions in ["sum", "min", "max"] and pa.types.is_duration( - pa_dtype - ): - request.node.add_marker(xfail_mark) elif pa.types.is_boolean(pa_dtype) and all_numeric_reductions in { "sem", "std",