@@ -387,25 +387,39 @@ def reversed(self) -> Block:
387387 index_labels = self .index .names ,
388388 )
389389
390- def reset_index (self , drop : bool = True ) -> Block :
390+ def reset_index (self , level : LevelsType = None , drop : bool = True ) -> Block :
391391 """Reset the index of the block, promoting the old index to a value column.
392392
393393 Arguments:
394+ level: the label or index level of the index levels to remove.
394395 name: this is the column id for the new value id derived from the old index
395396
396397 Returns:
397398 A new Block because dropping index columns can break references
398399 from Index classes that point to this block.
399400 """
401+ if level :
402+ # preserve original order, not user provided order
403+ level_ids : Sequence [str ] = [
404+ id for id in self .index_columns if id in self .index .resolve_level (level )
405+ ]
406+ else :
407+ level_ids = self .index_columns
408+
400409 expr = self ._expr
401- if (
410+ if set (self .index_columns ) > set (level_ids ):
411+ new_index_cols = [col for col in self .index_columns if col not in level_ids ]
412+ new_index_labels = [self .col_id_to_index_name [id ] for id in new_index_cols ]
413+ elif (
402414 self .session ._default_index_type
403415 == bigframes .enums .DefaultIndexKind .SEQUENTIAL_INT64
404416 ):
405417 expr , new_index_col_id = expr .promote_offsets ()
406418 new_index_cols = [new_index_col_id ]
419+ new_index_labels = [None ]
407420 elif self .session ._default_index_type == bigframes .enums .DefaultIndexKind .NULL :
408421 new_index_cols = []
422+ new_index_labels = []
409423 else :
410424 raise ValueError (
411425 f"Unrecognized default index kind: { self .session ._default_index_type } "
@@ -415,22 +429,23 @@ def reset_index(self, drop: bool = True) -> Block:
415429 # Even though the index might be part of the ordering, keep that
416430 # ordering expression as reset_index shouldn't change the row
417431 # order.
418- expr = expr .drop_columns (self . index_columns )
432+ expr = expr .drop_columns (level_ids )
419433 return Block (
420434 expr ,
421435 index_columns = new_index_cols ,
436+ index_labels = new_index_labels ,
422437 column_labels = self .column_labels ,
423438 )
424439 else :
425440 # Add index names to column index
426- index_labels = self .index .names
427441 column_labels_modified = self .column_labels
428- for level , label in enumerate (index_labels ):
442+ for position , level_id in enumerate (level_ids ):
443+ label = self .col_id_to_index_name [level_id ]
429444 if label is None :
430- if "index" not in self .column_labels and len ( index_labels ) <= 1 :
445+ if "index" not in self .column_labels and self . index . nlevels <= 1 :
431446 label = "index"
432447 else :
433- label = f"level_{ level } "
448+ label = f"level_{ self . index_columns . index ( level_id ) } "
434449
435450 if label in self .column_labels :
436451 raise ValueError (f"cannot insert { label } , already exists" )
@@ -439,11 +454,12 @@ def reset_index(self, drop: bool = True) -> Block:
439454 label = tuple (label if i == 0 else "" for i in range (nlevels ))
440455 # Create index copy with label inserted
441456 # See: https://pandas.pydata.org/docs/reference/api/pandas.Index.insert.html
442- column_labels_modified = column_labels_modified .insert (level , label )
457+ column_labels_modified = column_labels_modified .insert (position , label )
443458
444459 return Block (
445- expr ,
460+ expr . select_columns (( * new_index_cols , * level_ids , * self . value_columns )) ,
446461 index_columns = new_index_cols ,
462+ index_labels = new_index_labels ,
447463 column_labels = column_labels_modified ,
448464 )
449465
0 commit comments