diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index 4914d213accac..32f99c7852cca 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -411,6 +411,7 @@ Numeric - Bug in :meth:`DataFrame.rank` treating missing values and extreme values as equal (for example ``np.nan`` and ``np.inf``), causing incorrect results when ``na_option="bottom"`` or ``na_option="top`` used (:issue:`41931`) - Bug in ``numexpr`` engine still being used when the option ``compute.use_numexpr`` is set to ``False`` (:issue:`32556`) - Bug in :class:`DataFrame` arithmetic ops with a subclass whose :meth:`_constructor` attribute is a callable other than the subclass itself (:issue:`43201`) +- Bug in arithmetic operations involving :class:`RangeIndex` where the result would have the incorrect ``name`` (:issue:`43962`) - Conversion diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index 4003165a7ddc6..d219361dbdd57 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -885,9 +885,8 @@ def _arith_method(self, other, op): step = op # TODO: if other is a RangeIndex we may have more efficient options - other = extract_array(other, extract_numpy=True, extract_range=True) - - left, right = self, other + right = extract_array(other, extract_numpy=True, extract_range=True) + left = self try: # apply if we have an override @@ -907,7 +906,8 @@ def _arith_method(self, other, op): rstart = op(left.start, right) rstop = op(left.stop, right) - result = type(self)(rstart, rstop, rstep, name=self.name) + res_name = ops.get_op_result_name(self, other) + result = type(self)(rstart, rstop, rstep, name=res_name) # for compat with numpy / Int64Index # even if we can represent as a RangeIndex, return diff --git a/pandas/tests/arithmetic/test_numeric.py b/pandas/tests/arithmetic/test_numeric.py index f06e5e9bdc93b..ec17b9f0bfd52 100644 --- a/pandas/tests/arithmetic/test_numeric.py +++ b/pandas/tests/arithmetic/test_numeric.py @@ -693,11 +693,10 @@ def test_mul_float_series(self, numeric_idx): tm.assert_series_equal(result, expected) def test_mul_index(self, numeric_idx): - # in general not true for RangeIndex idx = numeric_idx - if not isinstance(idx, RangeIndex): - result = idx * idx - tm.assert_index_equal(result, idx ** 2) + + result = idx * idx + tm.assert_index_equal(result, idx ** 2) def test_mul_datelike_raises(self, numeric_idx): idx = numeric_idx @@ -1090,11 +1089,11 @@ def test_ufunc_compat(self, holder): box = Series if holder is Series else Index if holder is RangeIndex: - idx = RangeIndex(0, 5) + idx = RangeIndex(0, 5, name="foo") else: - idx = holder(np.arange(5, dtype="int64")) + idx = holder(np.arange(5, dtype="int64"), name="foo") result = np.sin(idx) - expected = box(np.sin(np.arange(5, dtype="int64"))) + expected = box(np.sin(np.arange(5, dtype="int64")), name="foo") tm.assert_equal(result, expected) @pytest.mark.parametrize("holder", [Int64Index, UInt64Index, Float64Index, Series]) @@ -1212,6 +1211,8 @@ class TestNumericArithmeticUnsorted: def check_binop(self, ops, scalars, idxs): for op in ops: for a, b in combinations(idxs, 2): + a = a._rename("foo") + b = b._rename("bar") result = op(a, b) expected = op(Int64Index(a), Int64Index(b)) tm.assert_index_equal(result, expected)