diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index 3e72072eae303..2ec575ef5040a 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -858,6 +858,7 @@ Other - Bug in :meth:`DataFrame.append` that raised ``IndexError`` when appending with empty list (:issue:`28769`) - Fix :class:`AbstractHolidayCalendar` to return correct results for years after 2030 (now goes up to 2200) (:issue:`27790`) +- Fixed :class:`IntegerArray` returning ``NA`` rather than ``inf`` for operations dividing by 0 (:issue:`27398`) - Bug in :meth:`Series.count` raises if use_inf_as_na is enabled (:issue:`29478`) diff --git a/pandas/core/arrays/integer.py b/pandas/core/arrays/integer.py index 08a3eca1e9055..d47e7e3df27e1 100644 --- a/pandas/core/arrays/integer.py +++ b/pandas/core/arrays/integer.py @@ -700,11 +700,6 @@ def _maybe_mask_result(self, result, mask, other, op_name): op_name : str """ - # may need to fill infs - # and mask wraparound - if is_float_dtype(result): - mask |= (result == np.inf) | (result == -np.inf) - # if we have a float operand we are by-definition # a float result # or our op is a divide @@ -748,7 +743,7 @@ def integer_arithmetic_method(self, other): # nans propagate if mask is None: - mask = self._mask + mask = self._mask.copy() else: mask = self._mask | mask diff --git a/pandas/tests/arrays/test_integer.py b/pandas/tests/arrays/test_integer.py index 90790ccadb54a..d36b42ec87e51 100644 --- a/pandas/tests/arrays/test_integer.py +++ b/pandas/tests/arrays/test_integer.py @@ -339,6 +339,19 @@ def test_error(self, data, all_arithmetic_operators): with pytest.raises(NotImplementedError): opa(np.arange(len(s)).reshape(-1, len(s))) + @pytest.mark.parametrize("zero, negative", [(0, False), (0.0, False), (-0.0, True)]) + def test_divide_by_zero(self, zero, negative): + # https://github.com/pandas-dev/pandas/issues/27398 + a = pd.array([0, 1, -1, None], dtype="Int64") + result = a / zero + expected = np.array([np.nan, np.inf, -np.inf, np.nan]) + if negative: + values = [np.nan, -np.inf, np.inf, np.nan] + else: + values = [np.nan, np.inf, -np.inf, np.nan] + expected = np.array(values) + tm.assert_numpy_array_equal(result, expected) + def test_pow(self): # https://github.com/pandas-dev/pandas/issues/22022 a = integer_array([1, np.nan, np.nan, 1]) @@ -389,6 +402,10 @@ def test_compare_array(self, data, all_compare_operators): other = pd.Series([0] * len(data)) self._compare_other(data, op_name, other) + def test_no_shared_mask(self, data): + result = data + 1 + assert np.shares_memory(result._mask, data._mask) is False + def test_compare_to_string(self, any_nullable_int_dtype): # GH 28930 s = pd.Series([1, None], dtype=any_nullable_int_dtype)