Skip to content

Commit b1e6c1f

Browse files
phoflmroeschke
andauthored
BUG: MultiIndex.append not checking names for equality (#48288)
* BUG: MultiIndex.append not checking names for equality * BUG: MultiIndex.append not checking names for equality * Update doc/source/whatsnew/v1.6.0.rst Co-authored-by: Matthew Roeschke <[email protected]> * Add test and fix bug * Improve name checking Co-authored-by: Matthew Roeschke <[email protected]>
1 parent 1843cf2 commit b1e6c1f

File tree

4 files changed

+34
-5
lines changed

4 files changed

+34
-5
lines changed

doc/source/whatsnew/v1.6.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ Missing
161161

162162
MultiIndex
163163
^^^^^^^^^^
164-
-
164+
- Bug in :meth:`MultiIndex.append` not checking names for equality (:issue:`48288`)
165165
-
166166

167167
I/O

pandas/core/indexes/multi.py

+7-3
Original file line numberDiff line numberDiff line change
@@ -2204,19 +2204,23 @@ def append(self, other):
22042204
if all(
22052205
(isinstance(o, MultiIndex) and o.nlevels >= self.nlevels) for o in other
22062206
):
2207-
arrays = []
2207+
arrays, names = [], []
22082208
for i in range(self.nlevels):
22092209
label = self._get_level_values(i)
22102210
appended = [o._get_level_values(i) for o in other]
22112211
arrays.append(label.append(appended))
2212-
return MultiIndex.from_arrays(arrays, names=self.names)
2212+
single_label_name = all(label.name == x.name for x in appended)
2213+
names.append(label.name if single_label_name else None)
2214+
return MultiIndex.from_arrays(arrays, names=names)
22132215

22142216
to_concat = (self._values,) + tuple(k._values for k in other)
22152217
new_tuples = np.concatenate(to_concat)
22162218

22172219
# if all(isinstance(x, MultiIndex) for x in other):
22182220
try:
2219-
return MultiIndex.from_tuples(new_tuples, names=self.names)
2221+
# We only get here if other contains at least one index with tuples,
2222+
# setting names to None automatically
2223+
return MultiIndex.from_tuples(new_tuples)
22202224
except (TypeError, IndexError):
22212225
return Index._with_infer(new_tuples)
22222226

pandas/core/reshape/pivot.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,13 @@ def _all_key(key):
391391
# GH31016 this is to calculate margin for each group, and assign
392392
# corresponded key as index
393393
transformed_piece = DataFrame(piece.apply(aggfunc)).T
394-
transformed_piece.index = Index([all_key], name=piece.index.name)
394+
if isinstance(piece.index, MultiIndex):
395+
# We are adding an empty level
396+
transformed_piece.index = MultiIndex.from_tuples(
397+
[all_key], names=piece.index.names + [None]
398+
)
399+
else:
400+
transformed_piece.index = Index([all_key], name=piece.index.name)
395401

396402
# append piece for margin into table_piece
397403
table_pieces.append(transformed_piece)

pandas/tests/indexes/multi/test_reshape.py

+19
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,25 @@ def test_append_index():
150150
tm.assert_index_equal(result, expected)
151151

152152

153+
@pytest.mark.parametrize("name, exp", [("b", "b"), ("c", None)])
154+
def test_append_names_match(name, exp):
155+
# GH#48288
156+
midx = MultiIndex.from_arrays([[1, 2], [3, 4]], names=["a", "b"])
157+
midx2 = MultiIndex.from_arrays([[3], [5]], names=["a", name])
158+
result = midx.append(midx2)
159+
expected = MultiIndex.from_arrays([[1, 2, 3], [3, 4, 5]], names=["a", exp])
160+
tm.assert_index_equal(result, expected)
161+
162+
163+
def test_append_names_dont_match():
164+
# GH#48288
165+
midx = MultiIndex.from_arrays([[1, 2], [3, 4]], names=["a", "b"])
166+
midx2 = MultiIndex.from_arrays([[3], [5]], names=["x", "y"])
167+
result = midx.append(midx2)
168+
expected = MultiIndex.from_arrays([[1, 2, 3], [3, 4, 5]], names=None)
169+
tm.assert_index_equal(result, expected)
170+
171+
153172
def test_repeat():
154173
reps = 2
155174
numbers = [1, 2, 3]

0 commit comments

Comments
 (0)