Skip to content

Commit 145a341

Browse files
Backport PR pandas-dev#48058 on branch 1.4.x (REGR: fix reset_index (Index.insert) regression with custom Index subclasses) (pandas-dev#48199)
Backport PR pandas-dev#48058: REGR: fix reset_index (Index.insert) regression with custom Index subclasses Co-authored-by: Joris Van den Bossche <[email protected]>
1 parent 7a1ec99 commit 145a341

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

doc/source/whatsnew/v1.4.4.rst

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Fixed regressions
2222
- Fixed regression in :meth:`DataFrame.loc` not aligning index in some cases when setting a :class:`DataFrame` (:issue:`47578`)
2323
- Fixed regression in :meth:`DataFrame.loc` setting a length-1 array like value to a single value in the DataFrame (:issue:`46268`)
2424
- Fixed regression in setting ``None`` or non-string value into a ``string``-dtype Series using a mask (:issue:`47628`)
25+
- Fixed regression using custom Index subclasses (for example, used in xarray) with :meth:`~DataFrame.reset_index` or :meth:`Index.insert` (:issue:`47071`)
2526
- Fixed regression in :meth:`DatetimeIndex.intersection` when the :class:`DatetimeIndex` has dates crossing daylight savings time (:issue:`46702`)
2627
- Fixed regression in :func:`merge` throwing an error when passing a :class:`Series` with a multi-level name (:issue:`47946`)
2728
- Fixed regression in :meth:`DataFrame.eval` creating a copy when updating inplace (:issue:`47449`)

pandas/core/indexes/base.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -6614,9 +6614,12 @@ def insert(self, loc: int, item) -> Index:
66146614
loc = loc if loc >= 0 else loc - 1
66156615
new_values[loc] = item
66166616

6617-
# Use self._constructor instead of Index to retain NumericIndex GH#43921
6618-
# TODO(2.0) can use Index instead of self._constructor
6619-
return self._constructor._with_infer(new_values, name=self.name)
6617+
if self._typ == "numericindex":
6618+
# Use self._constructor instead of Index to retain NumericIndex GH#43921
6619+
# TODO(2.0) can use Index instead of self._constructor
6620+
return self._constructor._with_infer(new_values, name=self.name)
6621+
else:
6622+
return Index._with_infer(new_values, name=self.name)
66206623

66216624
def drop(self, labels, errors: str_t = "raise") -> Index:
66226625
"""

pandas/tests/indexes/test_subclass.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
Tests involving custom Index subclasses
3+
"""
4+
import numpy as np
5+
6+
from pandas import (
7+
DataFrame,
8+
Index,
9+
)
10+
import pandas._testing as tm
11+
12+
13+
class CustomIndex(Index):
14+
def __new__(cls, data, name=None):
15+
# assert that this index class cannot hold strings
16+
if any(isinstance(val, str) for val in data):
17+
raise TypeError("CustomIndex cannot hold strings")
18+
19+
if name is None and hasattr(data, "name"):
20+
name = data.name
21+
data = np.array(data, dtype="O")
22+
23+
return cls._simple_new(data, name)
24+
25+
26+
def test_insert_fallback_to_base_index():
27+
# https://github.com/pandas-dev/pandas/issues/47071
28+
29+
idx = CustomIndex([1, 2, 3])
30+
result = idx.insert(0, "string")
31+
expected = Index(["string", 1, 2, 3], dtype=object)
32+
tm.assert_index_equal(result, expected)
33+
34+
df = DataFrame(
35+
np.random.randn(2, 3), columns=idx, index=Index([1, 2], name="string")
36+
)
37+
result = df.reset_index()
38+
tm.assert_index_equal(result.columns, expected)

0 commit comments

Comments
 (0)