class_docstr: Iteratively stratify a multi-label data set into folds
  
  Construct an interative stratifier that splits the data set into folds trying to maintain balanced representation
  with respect to order-th label combinations.
  
  Attributes
  ----------
  
  n_splits : number of splits, int
      the number of folds to stratify into
  
  order : int, >= 1
      the order of label relationship to take into account when balancing sample distribution across labels
  
  sample_distribution_per_fold : None or List[float], :code:`(n_splits)`
      desired percentage of samples in each of the folds, if None and equal distribution of samples per fold
      is assumed i.e. 1/n_splits for each fold. The value is held in :code:`self.percentage_per_fold`.
  
  shuffle : bool
      Whether to shuffle the data before splitting into batches. Note that the samples within each split
      will not be shuffled.
  
  random_state : int, RandomState instance or None
      integer to seed the RNG, or the RNG state to use; if None (the default), will use the global
      state of numpy RNG
docstr: Prepares variables for performing stratification
  
  For the purpose of clarity, the type Combination denotes List[int], :code:`(self.order)` and represents a
  label combination of the order we want to preserve among folds in stratification. The total number of
  combinations present in :code:`(y)` will be denoted as :code:`(n_combinations)`.
  
  Sets
  ----
  
  self.n_samples, self.n_labels : int, int
      shape of y
  
  self.desired_samples_per_fold: np.array[Float], :code:`(n_splits)`
      number of samples desired per fold
  
  self.desired_samples_per_combination_per_fold: Dict[Combination, np.array[Float]], :code:`(n_combinations, n_splits)`
      number of samples evidencing each combination desired per each fold
  
  Parameters
  ----------
  
  y : output matrix or array of arrays (n_samples, n_labels)
  
  Returns
  -------
  
  rows : List[List[int]], :code:`(n_samples, n_labels)`
      list of label indices assigned to each sample
  
  rows_used : Dict[int, bool], :code:`(n_samples)`
      boolean map from a given sample index to boolean value whether it has been already assigned to a fold or not
  
  all_combinations :  List[Combination], :code:`(n_combinations)`
      list of all label combinations of order self.order present in y
  
  per_row_combinations : List[Combination], :code:`(n_samples)`
      list of all label combinations of order self.order present in y per row
  
  samples_with_combination : Dict[Combination, List[int]], :code:`(n_combinations)`
      map from each label combination present in y to list of sample indexes that have this combination assigned
  
  folds: List[List[int]] (n_splits)
      list of lists to be populated with samples
docstr_tok: ["Prepares","variables","for","performing","stratification","For","the","purpose","of","clarity",",","the","type","Combination","denotes","List","[","int","]",",",":","code",":","`","(","self.order",")","`","and","represents","a","label","combination","of","the","order","we","want","to","preserve","among","folds","in","stratification",".","The","total","number","of","combinations","present","in",":","code",":","`","(","y",")","`","will","be","denoted","as",":","code",":","`","(","n_combinations",")","`",".","Sets","--","--","self.n_samples",",","self.n_labels",":","int",",","int","shape","of","y","self.desired_samples_per_fold",":","np.array","[","Float","]",",",":","code",":","`","(","n_splits",")","`","number","of","samples","desired","per","fold","self.desired_samples_per_combination_per_fold",":","Dict","[","Combination",",","np.array","[","Float","]","]",",",":","code",":","`","(","n_combinations",",","n_splits",")","`","number","of","samples","evidencing","each","combination","desired","per","each","fold","Parameters","--","--","--","--","--","y",":","output","matrix","or","array","of","arrays","(","n_samples",",","n_labels",")","Returns","--","--","--","-","rows",":","List","[","List","[","int","]","]",",",":","code",":","`","(","n_samples",",","n_labels",")","`","list","of","label","indices","assigned","to","each","sample","rows_used",":","Dict","[","int",",","bool","]",",",":","code",":","`","(","n_samples",")","`","boolean","map","from","a","given","sample","index","to","boolean","value","whether","it","has","been","already","assigned","to","a","fold","or","not","all_combinations",":","List","[","Combination","]",",",":","code",":","`","(","n_combinations",")","`","list","of","all","label","combinations","of","order","self.order","present","in","y","per_row_combinations",":","List","[","Combination","]",",",":","code",":","`","(","n_samples",")","`","list","of","all","label","combinations","of","order","self.order","present","in","y","per","row","samples_with_combination",":","Dict","[","Combination",",","List","[","int","]","]",",",":","code",":","`","(","n_combinations",")","`","map","from","each","label","combination","present","in","y","to","list","of","sample","indexes","that","have","this","combination","assigned","folds",":","List","[","List","[","int","]","]","(","n_splits",")","list","of","lists","to","be","populated","with","samples"]
code: def _prepare_stratification(self, y):
      """Prepares variables for performing stratification
  
      For the purpose of clarity, the type Combination denotes List[int], :code:`(self.order)` and represents a
      label combination of the order we want to preserve among folds in stratification. The total number of
      combinations present in :code:`(y)` will be denoted as :code:`(n_combinations)`.
  
      Sets
      ----
  
      self.n_samples, self.n_labels : int, int
          shape of y
  
      self.desired_samples_per_fold: np.array[Float], :code:`(n_splits)`
          number of samples desired per fold
  
      self.desired_samples_per_combination_per_fold: Dict[Combination, np.array[Float]], :code:`(n_combinations, n_splits)`
          number of samples evidencing each combination desired per each fold
  
      Parameters
      ----------
  
      y : output matrix or array of arrays (n_samples, n_labels)
  
      Returns
      -------
  
      rows : List[List[int]], :code:`(n_samples, n_labels)`
          list of label indices assigned to each sample
  
      rows_used : Dict[int, bool], :code:`(n_samples)`
          boolean map from a given sample index to boolean value whether it has been already assigned to a fold or not
  
      all_combinations :  List[Combination], :code:`(n_combinations)`
          list of all label combinations of order self.order present in y
  
      per_row_combinations : List[Combination], :code:`(n_samples)`
          list of all label combinations of order self.order present in y per row
  
      samples_with_combination : Dict[Combination, List[int]], :code:`(n_combinations)`
          map from each label combination present in y to list of sample indexes that have this combination assigned
  
      folds: List[List[int]] (n_splits)
          list of lists to be populated with samples
  
      """
      self.n_samples, self.n_labels = y.shape
      self.desired_samples_per_fold = np.array(
          [
              self.percentage_per_fold[i] * self.n_samples
              for i in range(self.n_splits)
          ]
      )
      rows = sp.lil_matrix(y).rows
      rows_used = {i: False for i in range(self.n_samples)}
      all_combinations = []
      per_row_combinations = [[] for i in range(self.n_samples)]
      samples_with_combination = {}
      folds = [[] for _ in range(self.n_splits)]
  
      # for every row
      for sample_index, label_assignment in enumerate(rows):
          # for every n-th order label combination
          # register combination in maps and lists used later
          for combination in itertools.combinations_with_replacement(
              label_assignment, self.order
          ):
              if combination not in samples_with_combination:
                  samples_with_combination[combination] = []
  
              samples_with_combination[combination].append(sample_index)
              all_combinations.append(combination)
              per_row_combinations[sample_index].append(combination)
  
      all_combinations = [list(x) for x in set(all_combinations)]
  
      self.desired_samples_per_combination_per_fold = {
          combination: np.array(
              [
                  len(evidence_for_combination)
                  * self.percentage_per_fold[j]
                  for j in range(self.n_splits)
              ]
          )
          for combination, evidence_for_combination in samples_with_combination.items()
      }
      return (
          rows,
          rows_used,
          all_combinations,
          per_row_combinations,
          samples_with_combination,
          folds,
      )
  
file_path: scikit-multilearn/skmultilearn/model_selection/iterative_stratification.py
imports: from sklearn.model_selection._split import _BaseKFold
  import numpy
  import scipy.sparse
  import itertools
  from sklearn.utils import check_random_state
label_desc: Use image node_id 2 for calling the IterativeStratification obj's underlying member method code with example usage: obj._prepare_stratification(y) and returns: rows,  rows_used,  all_combinations,  per_row_combinations,  samples_with_combination,  folds