code: def stack(frame, level=-1, dropna=True):
      """
      Convert DataFrame to Series with multi-level Index. Columns become the
      second level of the resulting hierarchical index
  
      Returns
      -------
      stacked : Series
      """
  
      def factorize(index):
          if index.is_unique:
              return index, np.arange(len(index))
          codes, categories = _factorize_from_iterable(index)
          return categories, codes
  
      N, K = frame.shape
  
      # Will also convert negative level numbers and check if out of bounds.
      level_num = frame.columns._get_level_number(level)
  
      if isinstance(frame.columns, MultiIndex):
          return _stack_multi_columns(
              frame, level_num=level_num, dropna=dropna
          )
      elif isinstance(frame.index, MultiIndex):
          new_levels = list(frame.index.levels)
          new_codes = [lab.repeat(K) for lab in frame.index.codes]
  
          clev, clab = factorize(frame.columns)
          new_levels.append(clev)
          new_codes.append(np.tile(clab, N).ravel())
  
          new_names = list(frame.index.names)
          new_names.append(frame.columns.name)
          new_index = MultiIndex(
              levels=new_levels,
              codes=new_codes,
              names=new_names,
              verify_integrity=False,
          )
      else:
          levels, (ilab, clab) = zip(
              *map(factorize, (frame.index, frame.columns))
          )
          codes = ilab.repeat(K), np.tile(clab, N).ravel()
          new_index = MultiIndex(
              levels=levels,
              codes=codes,
              names=[frame.index.name, frame.columns.name],
              verify_integrity=False,
          )
  
      if frame._is_homogeneous_type:
          # For homogeneous EAs, frame.values will coerce to object. So
          # we concatenate instead.
          dtypes = list(frame.dtypes.values)
          dtype = dtypes[0]
  
          if is_extension_array_dtype(dtype):
              arr = dtype.construct_array_type()
              new_values = arr._concat_same_type(
                  [col._values for _, col in frame.iteritems()]
              )
              new_values = _reorder_for_extension_array_stack(
                  new_values, N, K
              )
          else:
              # homogeneous, non-EA
              new_values = frame.values.ravel()
  
      else:
          # non-homogeneous
          new_values = frame.values.ravel()
  
      if dropna:
          mask = notna(new_values)
          new_values = new_values[mask]
          new_index = new_index[mask]
  
      return frame._constructor_sliced(new_values, index=new_index)
  
imports: from functools import partial
  import itertools
  import numpy
  from pandas._libs import algos, reshape
  from pandas._libs.sparse import IntIndex
  from pandas.compat import PY2, range, text_type, u, zip
  from pandas.core.dtypes.cast import maybe_promote
  from pandas.core.dtypes.common import ensure_platform_int, is_bool_dtype, is_extension_array_dtype, is_integer_dtype, is_list_like, is_object_dtype, needs_i8_conversion
  from pandas.core.dtypes.missing import notna
  from pandas import compat
  import pandas.core.algorithms
  from pandas.core.arrays import SparseArray
  from pandas.core.arrays.categorical import _factorize_from_iterable
  from pandas.core.frame import DataFrame
  from pandas.core.index import Index, MultiIndex
  from pandas.core.internals.arrays import extract_array
  from pandas.core.series import Series
  from pandas.core.sorting import compress_group_index, decons_obs_group_ids, get_compressed_ids, get_group_index
label_desc: Use image node_id 5 for calling a global function with example usage: stack(frame, level, dropna) and returns: frame, categories,  codes, _stack_multi_columns, index,  np