Skip to content

Commit b49ff3e

Browse files
authored
REF: share RangeIndex methods (#43952)
1 parent d30aeeb commit b49ff3e

File tree

6 files changed

+33
-55
lines changed

6 files changed

+33
-55
lines changed

pandas/core/indexes/base.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,8 @@ def take(
10271027
taken = algos.take(
10281028
self._values, indices, allow_fill=allow_fill, fill_value=self._na_value
10291029
)
1030-
return type(self)._simple_new(taken, name=self.name)
1030+
# _constructor so RangeIndex->Int64Index
1031+
return self._constructor._simple_new(taken, name=self.name)
10311032

10321033
@final
10331034
def _maybe_disallow_fill(self, allow_fill: bool, fill_value, indices) -> bool:
@@ -1097,7 +1098,8 @@ def repeat(self, repeats, axis=None):
10971098
nv.validate_repeat((), {"axis": axis})
10981099
res_values = self._values.repeat(repeats)
10991100

1100-
return type(self)._simple_new(res_values, name=self.name)
1101+
# _constructor so RangeIndex->Int64Index
1102+
return self._constructor._simple_new(res_values, name=self.name)
11011103

11021104
# --------------------------------------------------------------------
11031105
# Copying Methods
@@ -6298,7 +6300,8 @@ def delete(self: _IndexT, loc) -> _IndexT:
62986300
Index(['b'], dtype='object')
62996301
"""
63006302
res_values = np.delete(self._data, loc)
6301-
return type(self)._simple_new(res_values, name=self.name)
6303+
# _constructor so RangeIndex->Int64Index
6304+
return self._constructor._simple_new(res_values, name=self.name)
63026305

63036306
def insert(self, loc: int, item) -> Index:
63046307
"""

pandas/core/indexes/range.py

+10-37
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
cache_readonly,
2727
doc,
2828
)
29-
from pandas.util._exceptions import rewrite_exception
3029

3130
from pandas.core.dtypes.common import (
3231
ensure_platform_int,
@@ -189,17 +188,6 @@ def _data(self) -> np.ndarray:
189188
"""
190189
return np.arange(self.start, self.stop, self.step, dtype=np.int64)
191190

192-
@cache_readonly
193-
def _cached_int64index(self) -> Int64Index:
194-
return Int64Index._simple_new(self._data, name=self.name)
195-
196-
@property
197-
def _int64index(self) -> Int64Index:
198-
# wrap _cached_int64index so we can be sure its name matches self.name
199-
res = self._cached_int64index
200-
res._name = self._name
201-
return res
202-
203191
def _get_data_as_items(self):
204192
"""return a list of tuples of start, stop, step"""
205193
rng = self._range
@@ -425,24 +413,6 @@ def _get_indexer(
425413

426414
# --------------------------------------------------------------------
427415

428-
def repeat(self, repeats, axis=None) -> Int64Index:
429-
return self._int64index.repeat(repeats, axis=axis)
430-
431-
def delete(self, loc) -> Int64Index: # type: ignore[override]
432-
return self._int64index.delete(loc)
433-
434-
def take(
435-
self, indices, axis: int = 0, allow_fill: bool = True, fill_value=None, **kwargs
436-
) -> Int64Index:
437-
with rewrite_exception("Int64Index", type(self).__name__):
438-
return self._int64index.take(
439-
indices,
440-
axis=axis,
441-
allow_fill=allow_fill,
442-
fill_value=fill_value,
443-
**kwargs,
444-
)
445-
446416
def tolist(self) -> list[int]:
447417
return list(self._range)
448418

@@ -683,7 +653,8 @@ def _union(self, other: Index, sort):
683653
and (end_s - step_o <= end_o)
684654
):
685655
return type(self)(start_r, end_r + step_o, step_o)
686-
return self._int64index._union(other, sort=sort)
656+
657+
return super()._union(other, sort=sort)
687658

688659
def _difference(self, other, sort=None):
689660
# optimized set operation if we have another RangeIndex
@@ -857,7 +828,8 @@ def __floordiv__(self, other):
857828
start = self.start // other
858829
new_range = range(start, start + 1, 1)
859830
return self._simple_new(new_range, name=self.name)
860-
return self._int64index // other
831+
832+
return super().__floordiv__(other)
861833

862834
# --------------------------------------------------------------------
863835
# Reductions
@@ -891,21 +863,22 @@ def _arith_method(self, other, op):
891863
elif isinstance(other, (timedelta, np.timedelta64)):
892864
# GH#19333 is_integer evaluated True on timedelta64,
893865
# so we need to catch these explicitly
894-
return op(self._int64index, other)
866+
return super()._arith_method(other, op)
895867
elif is_timedelta64_dtype(other):
896868
# Must be an np.ndarray; GH#22390
897-
return op(self._int64index, other)
869+
return super()._arith_method(other, op)
898870

899871
if op in [
900872
operator.pow,
901873
ops.rpow,
902874
operator.mod,
903875
ops.rmod,
876+
operator.floordiv,
904877
ops.rfloordiv,
905878
divmod,
906879
ops.rdivmod,
907880
]:
908-
return op(self._int64index, other)
881+
return super()._arith_method(other, op)
909882

910883
step: Callable | None = None
911884
if op in [operator.mul, ops.rmul, operator.truediv, ops.rtruediv]:
@@ -946,5 +919,5 @@ def _arith_method(self, other, op):
946919

947920
except (ValueError, TypeError, ZeroDivisionError):
948921
# Defer to Int64Index implementation
949-
return op(self._int64index, other)
950-
# TODO: Do attrs get handled reliably?
922+
# test_arithmetic_explicit_conversions
923+
return super()._arith_method(other, op)

pandas/tests/arithmetic/test_numeric.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -1311,18 +1311,22 @@ def test_numeric_compat2(self):
13111311
# __pow__
13121312
idx = RangeIndex(0, 1000, 2)
13131313
result = idx ** 2
1314-
expected = idx._int64index ** 2
1314+
expected = Int64Index(idx._values) ** 2
13151315
tm.assert_index_equal(Index(result.values), expected, exact=True)
13161316

13171317
# __floordiv__
13181318
cases_exact = [
13191319
(RangeIndex(0, 1000, 2), 2, RangeIndex(0, 500, 1)),
13201320
(RangeIndex(-99, -201, -3), -3, RangeIndex(33, 67, 1)),
1321-
(RangeIndex(0, 1000, 1), 2, RangeIndex(0, 1000, 1)._int64index // 2),
1321+
(
1322+
RangeIndex(0, 1000, 1),
1323+
2,
1324+
Int64Index(RangeIndex(0, 1000, 1)._values) // 2,
1325+
),
13221326
(
13231327
RangeIndex(0, 100, 1),
13241328
2.0,
1325-
RangeIndex(0, 100, 1)._int64index // 2.0,
1329+
Int64Index(RangeIndex(0, 100, 1)._values) // 2.0,
13261330
),
13271331
(RangeIndex(0), 50, RangeIndex(0)),
13281332
(RangeIndex(2, 4, 2), 3, RangeIndex(0, 1, 1)),

pandas/tests/indexes/ranges/test_range.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -299,12 +299,12 @@ def test_identical(self, simple_index):
299299
def test_nbytes(self):
300300

301301
# memory savings vs int index
302-
i = RangeIndex(0, 1000)
303-
assert i.nbytes < i._int64index.nbytes / 10
302+
idx = RangeIndex(0, 1000)
303+
assert idx.nbytes < Int64Index(idx.values).nbytes / 10
304304

305305
# constant memory usage
306306
i2 = RangeIndex(0, 10)
307-
assert i.nbytes == i2.nbytes
307+
assert idx.nbytes == i2.nbytes
308308

309309
@pytest.mark.parametrize(
310310
"start,stop,step",

pandas/tests/indexes/ranges/test_setops.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ def test_union_sorted(self, unions):
286286
tm.assert_index_equal(res1, expected_notsorted, exact=True)
287287

288288
res2 = idx2.union(idx1, sort=None)
289-
res3 = idx1._int64index.union(idx2, sort=None)
289+
res3 = Int64Index(idx1._values, name=idx1.name).union(idx2, sort=None)
290290
tm.assert_index_equal(res2, expected_sorted, exact=True)
291291
tm.assert_index_equal(res3, expected_sorted)
292292

@@ -322,11 +322,11 @@ def test_difference_mismatched_step(self):
322322
obj = RangeIndex.from_range(range(1, 10), name="foo")
323323

324324
result = obj.difference(obj[::2])
325-
expected = obj[1::2]._int64index
325+
expected = Int64Index(obj[1::2]._values, name=obj.name)
326326
tm.assert_index_equal(result, expected, exact=True)
327327

328328
result = obj.difference(obj[1::2])
329-
expected = obj[::2]._int64index
329+
expected = Int64Index(obj[::2]._values, name=obj.name)
330330
tm.assert_index_equal(result, expected, exact=True)
331331

332332
def test_symmetric_difference(self):

pandas/tests/reductions/test_reductions.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -221,15 +221,15 @@ class TestIndexReductions:
221221
def test_max_min_range(self, start, stop, step):
222222
# GH#17607
223223
idx = RangeIndex(start, stop, step)
224-
expected = idx._int64index.max()
224+
expected = idx._values.max()
225225
result = idx.max()
226226
assert result == expected
227227

228228
# skipna should be irrelevant since RangeIndex should never have NAs
229229
result2 = idx.max(skipna=False)
230230
assert result2 == expected
231231

232-
expected = idx._int64index.min()
232+
expected = idx._values.min()
233233
result = idx.min()
234234
assert result == expected
235235

@@ -431,13 +431,11 @@ def test_numpy_minmax_range(self):
431431
# GH#26125
432432
idx = RangeIndex(0, 10, 3)
433433

434-
expected = idx._int64index.max()
435434
result = np.max(idx)
436-
assert result == expected
435+
assert result == 9
437436

438-
expected = idx._int64index.min()
439437
result = np.min(idx)
440-
assert result == expected
438+
assert result == 0
441439

442440
errmsg = "the 'out' parameter is not supported"
443441
with pytest.raises(ValueError, match=errmsg):

0 commit comments

Comments
 (0)