docs: def build_index_from_design(df, design, remove_prefix=None, types=None, axis=1, auto_convert_numeric=True, unmatched_columns='index'):
      """
      Build a MultiIndex from a design table.
  
      Supply with a table with column headings for the new multiindex
      and a index containing the labels to search for in the data.
  
      :param df:
      :param design:
      :param remove:
      :param types:
      :param axis:
      :param auto_convert_numeric:
      :return:
      """
  
      df = df.copy()
      if 'Label' not in design.index.names:
          design = design.set_index('Label')
  
      if remove_prefix is None:
          remove_prefix = []
      if type(remove_prefix) is str:
          remove_prefix=[remove_prefix]
  
      unmatched_for_index = []
  
      names = design.columns.values
      idx_levels = len(names)
      indexes = []
      
      # Convert numeric only columns_to_combine; except index
      if auto_convert_numeric:
          design = design.apply(pd.to_numeric, errors="ignore")
          # The match columns are always strings, so the index must also be
          design.index = design.index.astype(str)
      
      # Apply type settings
      if types:
          for n, t in types.items():
              if n in design.columns.values:
                  design[n] = design[n].astype(t)
      
      # Build the index
      for lo in df.columns.values:
  
          l = copy(lo)
          for s in remove_prefix:
              l = l.replace(s, '')
  
          # Remove trailing/forward spaces
          l = l.strip()
          # Convert to numeric if possible
          l = numeric(l)
          # Attempt to match to the labels
  
          try:
              # Index
              idx = design.loc[str(l)]
  
          except:
              if unmatched_columns:
                  unmatched_for_index.append(lo)
              else:
                  # No match, fill with None
                  idx = tuple([None] * idx_levels)
                  indexes.append(idx)
  
          else:
              # We have a matched row, store it
              idx = tuple(idx.values)
              indexes.append(idx)
  
      if axis == 0:
          df.index = pd.MultiIndex.from_tuples(indexes, names=names)
      else:
  
          # If using unmatched for index, append
          if unmatched_columns == 'index':
              df = df.set_index(unmatched_for_index, append=True)
  
          elif unmatched_columns == 'drop':
              df = df.drop(unmatched_for_index, axis=1)
  
          df.columns = pd.MultiIndex.from_tuples(indexes, names=names)
  
      df = df.sort_index(axis=1)
  
      return df