diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index c002832cd89bb..d7a8a2e3d5f87 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -6330,13 +6330,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: """