class_docstr: Helper class to unstack data / pivot with multi-level index
  
  Parameters
  ----------
  index : MultiIndex
  level : int or str, default last level
      Level to "unstack". Accepts a name for the level.
  fill_value : scalar, optional
      Default value to fill in missing values if subgroups do not have the
      same set of labels. By default, missing values will be replaced with
      the default fill value for that data type, NaN for float, NaT for
      datetimelike, etc. For integer types, by default data will converted to
      float and missing values will be set to NaN.
  constructor : object
      Pandas ``DataFrame`` or subclass used to create unstacked
      response.  If None, DataFrame will be used.
  
  Examples
  --------
  >>> index = pd.MultiIndex.from_tuples([('one', 'a'), ('one', 'b'),
  ...                                    ('two', 'a'), ('two', 'b')])
  >>> s = pd.Series(np.arange(1, 5, dtype=np.int64), index=index)
  >>> s
  one  a    1
       b    2
  two  a    3
       b    4
  dtype: int64
  
  >>> s.unstack(level=-1)
       a  b
  one  1  2
  two  3  4
  
  >>> s.unstack(level=0)
     one  two
  a    1    3
  b    2    4
  
  Returns
  -------
  unstacked : DataFrame
class_docstr_tok: ["Helper","class","to","unstack","data","\/","pivot","with","multi-level","index","Parameters","--","--","--","--","--","index",":","MultiIndex","level",":","int","or","str",",","default","last","level","Level","to","``","unstack","''",".","Accepts","a","name","for","the","level",".","fill_value",":","scalar",",","optional","Default","value","to","fill","in","missing","values","if","subgroups","do","not","have","the","same","set","of","labels",".","By","default",",","missing","values","will","be","replaced","with","the","default","fill","value","for","that","data","type",",","NaN","for","float",",","NaT","for","datetimelike",",","etc",".","For","integer","types",",","by","default","data","will","converted","to","float","and","missing","values","will","be","set","to","NaN",".","constructor",":","object","Pandas","``","DataFrame","``","or","subclass","used","to","create","unstacked","response",".","If","None",",","DataFrame","will","be","used",".","Examples","--","--","--","--",">",">",">","index","=","pd.MultiIndex.from_tuples","(","[","(","'one","'",",","'","a","'",")",",","(","'one","'",",","'","b","'",")",",","...","(","'two","'",",","'","a","'",")",",","(","'two","'",",","'","b","'",")","]",")",">",">",">","s","=","pd.Series","(","np.arange","(","1",",","5",",","dtype=np.int64",")",",","index=index",")",">",">",">","s","one","a","1","b","2","two","a","3","b","4","dtype",":","int64",">",">",">","s.unstack","(","level=-1",")","a","b","one","1","2","two","3","4",">",">",">","s.unstack","(","level=0",")","one","two","a","1","3","b","2","4","Returns","--","--","--","-","unstacked",":","DataFrame"]
code: def __init__(
      self, index: MultiIndex, level=-1, constructor=None
  ) -> None:
      if constructor is None:
          constructor = DataFrame
      self.constructor = constructor
  
      self.index = index.remove_unused_levels()
  
      self.level = self.index._get_level_number(level)
  
      # when index includes `nan`, need to lift levels/strides by 1
      self.lift = 1 if -1 in self.index.codes[self.level] else 0
  
      # Note: the "pop" below alters these in-place.
      self.new_index_levels = list(self.index.levels)
      self.new_index_names = list(self.index.names)
  
      self.removed_name = self.new_index_names.pop(self.level)
      self.removed_level = self.new_index_levels.pop(self.level)
      self.removed_level_full = index.levels[self.level]
  
      # Bug fix GH 20601
      # If the data frame is too big, the number of unique index combination
      # will cause int32 overflow on windows environments.
      # We want to check and raise an error before this happens
      num_rows = np.max(
          [index_level.size for index_level in self.new_index_levels]
      )
      num_columns = self.removed_level.size
  
      # GH20601: This forces an overflow if the number of cells is too high.
      num_cells = num_rows * num_columns
  
      # GH 26314: Previous ValueError raised was too restrictive for many users.
      if num_cells > np.iinfo(np.int32).max:
          warnings.warn(
              f"The following operation may generate {num_cells} cells "
              f"in the resulting pandas object.",
              PerformanceWarning,
              stacklevel=find_stack_level(),
          )
  
      self._make_selectors()
  
imports: from __future__ import annotations
  import itertools
  from typing import TYPE_CHECKING, cast
  import warnings
  import numpy
  import pandas._libs.reshape
  from pandas._typing import npt
  from pandas.errors import PerformanceWarning
  from pandas.util._decorators import cache_readonly
  from pandas.util._exceptions import find_stack_level
  from pandas.core.dtypes.cast import maybe_promote
  from pandas.core.dtypes.common import ensure_platform_int, is_1d_only_ea_dtype, is_extension_array_dtype, is_integer, needs_i8_conversion
  from pandas.core.dtypes.dtypes import ExtensionDtype
  from pandas.core.dtypes.missing import notna
  import pandas.core.algorithms
  from pandas.core.arrays.categorical import factorize_from_iterable
  from pandas.core.construction import ensure_wrapped_if_datetimelike
  from pandas.core.frame import DataFrame
  from pandas.core.indexes.api import Index, MultiIndex
  from pandas.core.series import Series
  from pandas.core.sorting import compress_group_index, decons_obs_group_ids, get_compressed_ids, get_group_index, get_group_index_sorter
label_desc: Use image node_id 1 to create a new _Unstacker object  with example: obj = _Unstacker(index, level, constructor)