Skip to content

Commit d5c7d77

Browse files
committed
REF: Avoid code duplication in RangeIndex.append
1 parent 5029592 commit d5c7d77

File tree

3 files changed

+47
-57
lines changed

3 files changed

+47
-57
lines changed

pandas/core/dtypes/common.py

+5-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

@@ -220,6 +220,10 @@ def is_categorical(arr):
220220
return isinstance(arr, ABCCategorical) or is_categorical_dtype(arr)
221221

222222

223+
def is_range(arr):
224+
return isinstance(arr, ABCRangeIndex)
225+
226+
223227
def is_datetimetz(arr):
224228
"""
225229
Check whether an array-like is a datetime array-like with a timezone

pandas/core/dtypes/concat.py

+38
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,38 @@ def convert_sparse(x, axis):
559562
# coerce to object if needed
560563
result = result.astype('object')
561564
return result
565+
566+
567+
def _concat_indexes_same_dtype_rangeindex(indexes):
568+
569+
start = step = next = None
570+
571+
for obj in indexes:
572+
if not len(obj):
573+
continue
574+
575+
if start is None:
576+
# This is set by the first non-empty index
577+
start = obj._start
578+
if step is None and len(obj) > 1:
579+
step = obj._step
580+
elif step is None:
581+
# First non-empty index had only one element
582+
if obj._start == start:
583+
return _concat_index_asobject(indexes)
584+
step = obj._start - start
585+
586+
non_consecutive = ((step != obj._step and len(obj) > 1) or
587+
(next is not None and obj._start != next))
588+
if non_consecutive:
589+
# Not nice... but currently what happens in NumericIndex:
590+
return _concat_index_asobject(indexes)
591+
592+
if step is not None:
593+
next = obj[-1] + step
594+
595+
if start is None:
596+
start = obj._start
597+
step = obj._step
598+
stop = obj._stop if next is None else next
599+
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
449+
).rename(name)
502450

503451
def __len__(self):
504452
"""

0 commit comments

Comments
 (0)