@@ -3158,6 +3158,60 @@ def _get_level_values(self, level):
3158
3158
3159
3159
get_level_values = _get_level_values
3160
3160
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
+
3161
3215
_index_shared_docs ['get_indexer' ] = """
3162
3216
Compute indexer and mask for new index given the current index. The
3163
3217
indexer should be then used as an input to ndarray.take to align the
0 commit comments