Skip to content

Commit d06fb91

Browse files
authored
BUG: MultiIndex dtypes incorrect if level names not unique (#45175)
1 parent 30297db commit d06fb91

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

doc/source/whatsnew/v1.4.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,7 @@ MultiIndex
838838
- Bug in :meth:`MultiIndex.get_loc` raising ``TypeError`` instead of ``KeyError`` on nested tuple (:issue:`42440`)
839839
- Bug in :meth:`MultiIndex.union` setting wrong ``sortorder`` causing errors in subsequent indexing operations with slices (:issue:`44752`)
840840
- Bug in :meth:`MultiIndex.putmask` where the other value was also a :class:`MultiIndex` (:issue:`43212`)
841+
- Bug in :meth:`MultiIndex.dtypes` duplicate level names returned only one dtype per name (:issue:`45174`)
841842
-
842843

843844
I/O

pandas/core/indexes/multi.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -739,9 +739,7 @@ def dtypes(self) -> Series:
739739
from pandas import Series
740740

741741
names = com.fill_missing_names([level.name for level in self.levels])
742-
return Series(
743-
{names[idx]: level.dtype for idx, level in enumerate(self.levels)}
744-
)
742+
return Series([level.dtype for level in self.levels], index=names)
745743

746744
def __len__(self) -> int:
747745
return len(self.codes[0])

pandas/tests/indexes/multi/test_get_set.py

+17
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,23 @@ def test_get_dtypes_no_level_name():
6767
tm.assert_series_equal(expected, idx_multitype.dtypes)
6868

6969

70+
def test_get_dtypes_duplicate_level_names():
71+
# Test MultiIndex.dtypes with non-unique level names (# GH45174)
72+
result = MultiIndex.from_product(
73+
[
74+
[1, 2, 3],
75+
["a", "b", "c"],
76+
pd.date_range("20200101", periods=2, tz="UTC"),
77+
],
78+
names=["A", "A", "A"],
79+
).dtypes
80+
expected = pd.Series(
81+
[np.dtype("int64"), np.dtype("O"), DatetimeTZDtype(tz="utc")],
82+
index=["A", "A", "A"],
83+
)
84+
tm.assert_series_equal(result, expected)
85+
86+
7087
def test_get_level_number_out_of_bounds(multiindex_dataframe_random_data):
7188
frame = multiindex_dataframe_random_data
7289

0 commit comments

Comments
 (0)