diff --git a/asv_bench/benchmarks/index_object.py b/asv_bench/benchmarks/index_object.py index 454d9ccdda102..7697c3b9d3840 100644 --- a/asv_bench/benchmarks/index_object.py +++ b/asv_bench/benchmarks/index_object.py @@ -219,3 +219,22 @@ def time_min(self): def time_min_trivial(self): self.idx_inc.min() + + +class IndexOps(object): + goal_time = 0.2 + + def setup(self): + N = 10000 + self.ridx = [RangeIndex(i * 100, (i + 1) * 100) for i in range(N)] + self.iidx = [idx.astype(int) for idx in self.ridx] + self.oidx = [idx.astype(str) for idx in self.iidx] + + def time_concat_range(self): + self.ridx[0].append(self.ridx[1:]) + + def time_concat_int(self): + self.iidx[0].append(self.iidx[1:]) + + def time_concat_obj(self): + self.oidx[0].append(self.oidx[1:]) diff --git a/pandas/core/dtypes/concat.py b/pandas/core/dtypes/concat.py index 93993fd0a0cab..4e15aa50e4319 100644 --- a/pandas/core/dtypes/concat.py +++ b/pandas/core/dtypes/concat.py @@ -467,6 +467,11 @@ def _concat_datetimetz(to_concat, name=None): return to_concat[0]._simple_new(new_values, tz=tz, name=name) +def _concat_index_same_dtype(indexes, klass=None): + klass = klass if klass is not None else indexes[0].__class__ + return klass(np.concatenate([x._values for x in indexes])) + + def _concat_index_asobject(to_concat, name=None): """ concat all inputs as object. DatetimeIndex, TimedeltaIndex and @@ -581,16 +586,15 @@ def _concat_rangeindex_same_dtype(indexes): elif step is None: # First non-empty index had only one element if obj._start == start: - return _concat_index_asobject(indexes) + from pandas import Int64Index + return _concat_index_same_dtype(indexes, klass=Int64Index) step = obj._start - start non_consecutive = ((step != obj._step and len(obj) > 1) or (next is not None and obj._start != next)) if non_consecutive: - # Int64Index._append_same_dtype([ix.astype(int) for ix in indexes]) - # would be preferred... but it currently resorts to - # _concat_index_asobject anyway. - return _concat_index_asobject(indexes) + from pandas import Int64Index + return _concat_index_same_dtype(indexes, klass=Int64Index) if step is not None: next = obj[-1] + step diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 1f007b1961e06..b0703869948c2 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -17,6 +17,7 @@ from pandas.core.indexes.base import ( Index, InvalidIndexError, _index_shared_docs) from pandas.util._decorators import Appender, cache_readonly +import pandas.core.dtypes.concat as _concat import pandas.core.indexes.base as ibase @@ -96,6 +97,9 @@ def _assert_safe_casting(cls, data, subarr): """ pass + def _concat_same_dtype(self, indexes, name): + return _concat._concat_index_same_dtype(indexes).rename(name) + @property def is_all_dates(self): """