diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index cd1cb0b64f74a..726c9b8bde91d 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -660,6 +660,7 @@ Other - Bug in :meth:`Series.map` not raising on invalid ``na_action`` (:issue:`32815`) - Bug in :meth:`DataFrame.__dir__` caused a segfault when using unicode surrogates in a column name (:issue:`25509`) - Bug in :meth:`DataFrame.plot.scatter` caused an error when plotting variable marker sizes (:issue:`32904`) +- :class:`IntegerArray` now implements the ``sum`` operation (:issue:`33172`) .. --------------------------------------------------------------------------- diff --git a/pandas/compat/numpy/function.py b/pandas/compat/numpy/function.py index 260cc69187d38..30b4a365ad912 100644 --- a/pandas/compat/numpy/function.py +++ b/pandas/compat/numpy/function.py @@ -252,6 +252,7 @@ def validate_cum_func_with_skipna(skipna, args, kwargs, name): STAT_FUNC_DEFAULTS["out"] = None PROD_DEFAULTS = SUM_DEFAULTS = STAT_FUNC_DEFAULTS.copy() +SUM_DEFAULTS["axis"] = None SUM_DEFAULTS["keepdims"] = False SUM_DEFAULTS["initial"] = None diff --git a/pandas/core/arrays/integer.py b/pandas/core/arrays/integer.py index 5605b3fbc5dfa..9d41071755e6f 100644 --- a/pandas/core/arrays/integer.py +++ b/pandas/core/arrays/integer.py @@ -7,6 +7,7 @@ from pandas._libs import lib, missing as libmissing from pandas._typing import ArrayLike from pandas.compat import set_function_name +from pandas.compat.numpy import function as nv from pandas.util._decorators import cache_readonly from pandas.core.dtypes.base import ExtensionDtype @@ -573,6 +574,13 @@ def _reduce(self, name: str, skipna: bool = True, **kwargs): return result + def sum(self, skipna=True, min_count=0, **kwargs): + nv.validate_sum((), kwargs) + result = masked_reductions.sum( + values=self._data, mask=self._mask, skipna=skipna, min_count=min_count + ) + return result + def _maybe_mask_result(self, result, mask, other, op_name: str): """ Parameters diff --git a/pandas/tests/arrays/integer/test_function.py b/pandas/tests/arrays/integer/test_function.py index bdf902d1aca62..44c3077228e80 100644 --- a/pandas/tests/arrays/integer/test_function.py +++ b/pandas/tests/arrays/integer/test_function.py @@ -113,6 +113,26 @@ def test_value_counts_empty(): tm.assert_series_equal(result, expected) +@pytest.mark.parametrize("skipna", [True, False]) +@pytest.mark.parametrize("min_count", [0, 4]) +def test_integer_array_sum(skipna, min_count): + arr = pd.array([1, 2, 3, None], dtype="Int64") + result = arr.sum(skipna=skipna, min_count=min_count) + if skipna and min_count == 0: + assert result == 6 + else: + assert result is pd.NA + + +@pytest.mark.parametrize( + "values, expected", [([1, 2, 3], 6), ([1, 2, 3, None], 6), ([None], 0)] +) +def test_integer_array_numpy_sum(values, expected): + arr = pd.array(values, dtype="Int64") + result = np.sum(arr) + assert result == expected + + # TODO(jreback) - these need testing / are broken # shift