diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index 78e7a8516178a..5312dfe84cfd8 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -707,7 +707,12 @@ def dtypes(self) -> "Series": """ from pandas import Series - return Series({level.name: level.dtype for level in self.levels}) + return Series( + { + f"level_{idx}" if level.name is None else level.name: level.dtype + for idx, level in enumerate(self.levels) + } + ) @property def shape(self) -> Shape: diff --git a/pandas/tests/indexes/multi/test_get_set.py b/pandas/tests/indexes/multi/test_get_set.py index 83cebf90623fe..d43ee3330ef08 100644 --- a/pandas/tests/indexes/multi/test_get_set.py +++ b/pandas/tests/indexes/multi/test_get_set.py @@ -45,6 +45,25 @@ def test_get_dtypes(): tm.assert_series_equal(expected, idx_multitype.dtypes) +def test_get_dtypes_no_level_name(): + # Test MultiIndex.dtypes (# GH38580 ) + idx_multitype = MultiIndex.from_product( + [ + [1, 2, 3], + ["a", "b", "c"], + pd.date_range("20200101", periods=2, tz="UTC"), + ], + ) + expected = pd.Series( + { + "level_0": np.dtype("int64"), + "level_1": np.dtype("O"), + "level_2": DatetimeTZDtype(tz="utc"), + } + ) + tm.assert_series_equal(expected, idx_multitype.dtypes) + + def test_get_level_number_out_of_bounds(multiindex_dataframe_random_data): frame = multiindex_dataframe_random_data