@@ -3158,6 +3158,60 @@ def _get_level_values(self, level):
31583158
31593159 get_level_values = _get_level_values
31603160
3161+ def droplevel (self , level = 0 ):
3162+ """
3163+ Return index with requested level(s) removed. If resulting index has
3164+ only 1 level left, the result will be of Index type, not MultiIndex.
3165+
3166+ .. versionadded:: 0.23.1 (support for non-MultiIndex)
3167+
3168+ Parameters
3169+ ----------
3170+ level : int, str, or list-like, default 0
3171+ If a string is given, must be the name of a level
3172+ If list-like, elements must be names or indexes of levels.
3173+
3174+ Returns
3175+ -------
3176+ index : Index or MultiIndex
3177+ """
3178+ if not isinstance (level , (tuple , list )):
3179+ level = [level ]
3180+
3181+ levnums = sorted (self ._get_level_number (lev ) for lev in level )[::- 1 ]
3182+
3183+ if len (level ) == 0 :
3184+ return self
3185+ if len (level ) >= self .nlevels :
3186+ raise ValueError ("Cannot remove {} levels from an index with {} "
3187+ "levels: at least one level must be "
3188+ "left." .format (len (level ), self .nlevels ))
3189+ # The two checks above guarantee that here self is a MultiIndex
3190+
3191+ new_levels = list (self .levels )
3192+ new_labels = list (self .labels )
3193+ new_names = list (self .names )
3194+
3195+ for i in levnums :
3196+ new_levels .pop (i )
3197+ new_labels .pop (i )
3198+ new_names .pop (i )
3199+
3200+ if len (new_levels ) == 1 :
3201+
3202+ # set nan if needed
3203+ mask = new_labels [0 ] == - 1
3204+ result = new_levels [0 ].take (new_labels [0 ])
3205+ if mask .any ():
3206+ result = result .putmask (mask , np .nan )
3207+
3208+ result .name = new_names [0 ]
3209+ return result
3210+ else :
3211+ from .multi import MultiIndex
3212+ return MultiIndex (levels = new_levels , labels = new_labels ,
3213+ names = new_names , verify_integrity = False )
3214+
31613215 _index_shared_docs ['get_indexer' ] = """
31623216 Compute indexer and mask for new index given the current index. The
31633217 indexer should be then used as an input to ndarray.take to align the
0 commit comments