code: def resample(protected, y, type="uniform", probs=None, verbose=True):
      """Returns indices of observations for data.
  
      Method of bias mitigation. Similarly to 'reweight'
      this method computes desired number of observations just
      if the protected variable was independent from y and
      on this basis decides if this subgroup with certain class
      (favorable or not) should be more or less numerous. Than performs
      oversampling or undersampling depending on the case.
      If type of sampling is set to 'preferential' and probs
      are provided than instead of uniform sampling preferential
      sampling will be performed. Preferential sampling depending on the case
      will sample observations close to border or far from border.
  
      Parameters
      -----------
      protected : np.ndarray (1d)
          Vector, preferably 1-dimensional np.ndarray containing strings,
          which denotes the membership to a subgroup.
          NOTE: List and pd.Series are also supported; however, if provided,
          they will be transformed into a np.ndarray (1d) with dtype 'U'.
      y : pd.Series or pd.DataFrame or np.ndarray (1d)
          Target variable with outputs / scores. It shall have the same length as `protected`
      type : {'uniform', 'preferential'}
          Type indicates what strategy to use when choosing the samples.
          (default is 'uniform')
      probs : np.ndarray (1d)
          Vector with probabilities for each sample. Note that this should be
          probabilities for favourable outcome. For the best performance they
          should be consistent with 'y' but it is not required. This argument
          is required when using strategy of type 'preferential'
      verbose : bool
          Print messages about changes of types in 'y' and 'protected' (default is `True`).
  
      Returns
      -----------
      numpy.ndarray (1d)
          Array with indices for the data.
  
      Notes
      -----------
          - https://link.springer.com/content/pdf/10.1007/s10115-011-0463-8.pdf
      """
      if type == "preferential" and probs is None:
          raise ParameterCheckError(
              "when using type 'preferential' probabilities (probs) must be provided"
          )
  
      if type not in set(["uniform", "preferential"]):
          raise ParameterCheckError(
              "type must be either 'uniform' or 'preferential'"
          )
  
      protected = basic_checks.check_protected(protected, verbose)
      y = basic_checks.check_y(y, verbose)
  
      if type == "preferential":
          try:
              probs = np.asarray(probs)
              helper.verbose_cat(
                  "converted 'probs' to numpy array", verbose=verbose
              )
          except Exception:
              raise ParameterCheckError(
                  "try converting 'probs' to 1D numpy array"
              )
  
          if probs.ndim != 1 or len(probs) != len(y):
              raise ParameterCheckError(
                  "probs parameter must 1D numpy array with the same length as y"
              )
  
      weights = reweight(protected, y, verbose=False)
  
      expected_size = dict.fromkeys(np.unique(protected))
      for key in expected_size.keys():
          expected_size[key] = dict.fromkeys(np.unique(y))
  
      for subgroup in expected_size.keys():
          for value in np.unique(y):
              case_weights = weights[
                  (subgroup == protected) & (value == y)
              ]
              case_size = len(case_weights)
              weight = case_weights[0]
              expected_size[subgroup][value] = round(case_size * weight)
  
      indices = []
  
      for subgroup in expected_size.keys():
          for value in np.unique(y):
              current_case = np.arange(len(y))[
                  (protected == subgroup) & (y == value)
              ]
              expected = expected_size[subgroup][value]
              actual = np.sum((protected == subgroup) & (y == value))
              if expected == actual:
                  indices += list(current_case)
  
              elif expected < actual:
                  if type == "uniform":
                      indices += list(
                          np.random.choice(
                              current_case, expected, replace=False
                          )
                      )
                  else:
                      sorted_current_case = current_case[
                          np.argsort(probs[current_case])
                      ]
                      if value == 0:
                          indices += list(
                              sorted_current_case[:expected]
                          )
                      if value == 1:
                          indices += list(
                              sorted_current_case[-expected:]
                          )
              else:
                  if type == "uniform":
                      u_ind = list(
                          np.repeat(current_case, expected // actual)
                      )
                      u_ind += list(
                          np.random.choice(
                              current_case, expected % actual
                          )
                      )
  
                      indices += u_ind
  
                  else:
                      sorted_current_case = current_case[
                          np.argsort(probs[current_case])
                      ]
                      p_ind = list(
                          np.repeat(current_case, expected // actual)
                      )
  
                      if expected % actual != 0:
                          if value == 0:
                              p_ind += list(
                                  sorted_current_case[
                                      -(expected % actual) :
                                  ]
                              )
                          if value == 1:
                              p_ind += list(
                                  sorted_current_case[
                                      : (expected % actual)
                                  ]
                              )
  
                      indices += p_ind
  
      return np.array(indices)
  
file_path: DALEX/python/dalex/dalex/fairness/_group_fairness/mitigation.py
imports: import copy
  import numpy
  import dalex.datasets
  from .None import checks
  from .._basics import checks
  from .._basics.exceptions import ParameterCheckError
  from ..._explainer import helper
label_desc: Use image node_id 3 for calling a global function with example usage: resample(protected, y, type, probs, verbose) and returns: np