From c021d33ecf0e096a186edb731964767e9288a875 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sun, 10 Oct 2021 14:41:14 -0700 Subject: [PATCH] PERF: Index.insert (#43953) --- pandas/core/indexes/base.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 5555c11eb7b69..90db8d67f0637 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -6337,13 +6337,24 @@ def insert(self, loc: int, item) -> Index: dtype = self._find_common_type_compat(item) return self.astype(dtype).insert(loc, item) - arr = np.asarray(self) + arr = self._values + + if arr.dtype != object or not isinstance( + item, (tuple, np.datetime64, np.timedelta64) + ): + # with object-dtype we need to worry about numpy incorrectly casting + # dt64/td64 to integer, also about treating tuples as sequences + # special-casing dt64/td64 https://github.com/numpy/numpy/issues/12550 + casted = arr.dtype.type(item) + new_values = np.insert(arr, loc, casted) + + else: + new_values = np.insert(arr, loc, None) + new_values[loc] = item - # Use constructor to ensure we get tuples cast correctly. # Use self._constructor instead of Index to retain NumericIndex GH#43921 - item = self._constructor([item], dtype=self.dtype)._values - idx = np.concatenate((arr[:loc], item, arr[loc:])) - return self._constructor._with_infer(idx, name=self.name) + # TODO(2.0) can use Index instead of self._constructor + return self._constructor._with_infer(new_values, name=self.name) def drop(self, labels, errors: str_t = "raise") -> Index: """