@@ -620,16 +620,6 @@ def from_frame(cls, df, sortorder=None, names=None):
620
620
621
621
# --------------------------------------------------------------------
622
622
623
- @property
624
- def levels (self ):
625
- result = [
626
- x ._shallow_copy (name = name ) for x , name in zip (self ._levels , self ._names )
627
- ]
628
- for level in result :
629
- # disallow midx.levels[0].name = "foo"
630
- level ._no_setting_name = True
631
- return FrozenList (result )
632
-
633
623
@property
634
624
def _values (self ):
635
625
# We override here, since our parent uses _data, which we don't use.
@@ -659,6 +649,22 @@ def array(self):
659
649
"'MultiIndex.to_numpy()' to get a NumPy array of tuples."
660
650
)
661
651
652
+ # --------------------------------------------------------------------
653
+ # Levels Methods
654
+
655
+ @cache_readonly
656
+ def levels (self ):
657
+ # Use cache_readonly to ensure that self.get_locs doesn't repeatedly
658
+ # create new IndexEngine
659
+ # https://github.com/pandas-dev/pandas/issues/31648
660
+ result = [
661
+ x ._shallow_copy (name = name ) for x , name in zip (self ._levels , self ._names )
662
+ ]
663
+ for level in result :
664
+ # disallow midx.levels[0].name = "foo"
665
+ level ._no_setting_name = True
666
+ return FrozenList (result )
667
+
662
668
def _set_levels (
663
669
self , levels , level = None , copy = False , validate = True , verify_integrity = False
664
670
):
@@ -1227,6 +1233,9 @@ def _set_names(self, names, level=None, validate=True):
1227
1233
)
1228
1234
self ._names [lev ] = name
1229
1235
1236
+ # If .levels has been accessed, the names in our cache will be stale.
1237
+ self ._reset_cache ()
1238
+
1230
1239
names = property (
1231
1240
fset = _set_names , fget = _get_names , doc = """\n Names of levels in MultiIndex.\n """
1232
1241
)
0 commit comments