Skip to content

Commit 059c948

Browse files
committed
REF: Avoid code duplication in RangeIndex.append
1 parent 1f8e1bc commit 059c948

File tree

3 files changed

+44
-57
lines changed

3 files changed

+44
-57
lines changed

pandas/core/dtypes/common.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from .generic import (ABCCategorical, ABCPeriodIndex,
1313
ABCDatetimeIndex, ABCSeries,
1414
ABCSparseArray, ABCSparseSeries, ABCCategoricalIndex,
15-
ABCIndexClass)
15+
ABCIndexClass, ABCRangeIndex)
1616
from .inference import is_string_like
1717
from .inference import * # noqa
1818

@@ -219,6 +219,8 @@ def is_categorical(arr):
219219

220220
return isinstance(arr, ABCCategorical) or is_categorical_dtype(arr)
221221

222+
def is_range(arr):
223+
return isinstance(arr, ABCRangeIndex)
222224

223225
def is_datetimetz(arr):
224226
"""

pandas/core/dtypes/concat.py

+37
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
is_object_dtype,
1616
is_bool_dtype,
1717
is_dtype_equal,
18+
is_range,
1819
_NS_DTYPE,
1920
_TD_DTYPE)
2021
from pandas.core.dtypes.generic import (
@@ -45,6 +46,8 @@ def get_dtype_kinds(l):
4546
# if to_concat contains different tz,
4647
# the result must be object dtype
4748
typ = str(arr.dtype)
49+
elif is_range(arr):
50+
typ = 'range'
4851
elif is_datetime64_dtype(dtype):
4952
typ = 'datetime'
5053
elif is_timedelta64_dtype(dtype):
@@ -559,3 +562,37 @@ def convert_sparse(x, axis):
559562
# coerce to object if needed
560563
result = result.astype('object')
561564
return result
565+
566+
def _concat_indexes_same_dtype_rangeindex(indexes):
567+
568+
start = step = next = None
569+
570+
for obj in indexes:
571+
if not len(obj):
572+
continue
573+
574+
if start is None:
575+
# This is set by the first non-empty index
576+
start = obj._start
577+
if step is None and len(obj) > 1:
578+
step = obj._step
579+
elif step is None:
580+
# First non-empty index had only one element
581+
if obj._start == start:
582+
return _concat_index_asobject(indexes)
583+
step = obj._start - start
584+
585+
non_consecutive = ((step != obj._step and len(obj) > 1) or
586+
(next is not None and obj._start != next))
587+
if non_consecutive:
588+
# Not nice... but currently what happens in NumericIndex:
589+
return _concat_index_asobject(indexes)
590+
591+
if step is not None:
592+
next = obj[-1] + step
593+
594+
if start is None:
595+
start = obj._start
596+
step = obj._step
597+
stop = obj._stop if next is None else next
598+
return indexes[0].__class__(start, stop, step)

pandas/core/indexes/range.py

+4-56
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from pandas.compat.numpy import function as nv
1515
from pandas.core.indexes.base import Index, _index_shared_docs
1616
from pandas.util._decorators import Appender, cache_readonly
17+
import pandas.core.dtypes.concat as _concat
1718
import pandas.core.indexes.base as ibase
1819

1920
from pandas.core.indexes.numeric import Int64Index
@@ -443,62 +444,9 @@ def join(self, other, how='left', level=None, return_indexers=False,
443444
return super(RangeIndex, self).join(other, how, level, return_indexers,
444445
sort)
445446

446-
def append(self, other):
447-
"""
448-
Append a collection of Index options together
449-
450-
Parameters
451-
----------
452-
other : Index or list/tuple of indices
453-
454-
Returns
455-
-------
456-
appended : RangeIndex if all indexes are consecutive RangeIndexes,
457-
otherwise Int64Index or Index
458-
"""
459-
460-
to_concat = [self]
461-
462-
if isinstance(other, (list, tuple)):
463-
to_concat = to_concat + list(other)
464-
else:
465-
to_concat.append(other)
466-
467-
if not all([isinstance(i, RangeIndex) for i in to_concat]):
468-
return super(RangeIndex, self).append(other)
469-
470-
start = step = next = None
471-
472-
for obj in to_concat:
473-
if not len(obj):
474-
continue
475-
476-
if start is None:
477-
# This is set by the first non-empty index
478-
start = obj._start
479-
if step is None and len(obj) > 1:
480-
step = obj._step
481-
elif step is None:
482-
# First non-empty index had only one element
483-
if obj._start == start:
484-
return super(RangeIndex, self).append(other)
485-
step = obj._start - start
486-
487-
non_consecutive = ((step != obj._step and len(obj) > 1) or
488-
(next is not None and obj._start != next))
489-
if non_consecutive:
490-
return super(RangeIndex, self).append(other)
491-
492-
if step is not None:
493-
next = obj[-1] + step
494-
495-
if start is None:
496-
start = obj._start
497-
step = obj._step
498-
stop = obj._stop if next is None else next
499-
names = set([obj.name for obj in to_concat])
500-
name = None if len(names) > 1 else self.name
501-
return RangeIndex(start, stop, step, name=name)
447+
def _append_same_dtype(self, indexes, name):
448+
return _concat._concat_indexes_same_dtype_rangeindex(indexes).rename(
449+
name)
502450

503451
def __len__(self):
504452
"""

0 commit comments

Comments
 (0)