code: def sample_reference(
      x,
      n: Optional[int] = None,
      cat_cols: List[str] = [],
      seed: Optional[int] = None,
      ref_range: Optional[Dict] = None,
  ):
      """
      Generate samples from a uniform distribution over the columns of X.
  
      :param x: 2D array of samples, where each column corresponds to a feature.
      :type x: Pandas Dataframe or Numpy Array
      :param n: Number of samples to draw, defaults to the same number as the samples provided.
      :type n: Optional[int], optional
      :param cat_cols: Set of categorical columns, defaults to None
      :type cat_cols: List[str], optional
      :param seed: Random seed for uniform sampling, defaults to None
      :type seed: int, optional
      :param ref_range: Manual override of the range for reference samples, given as a dictionary of the form
          `ref_range = {c: {"is_binary": True/False, "min": min_value, "max": max_value}}`
      :type ref_range: Optional[Dict], optional
      """
  
      if n is None:
          n = x.shape[0]
  
      rng = np.random.default_rng(seed)
  
      data = x if isinstance(x, pd.DataFrame) else pd.DataFrame(x)
  
      if ref_range is not None:
          assert isinstance(ref_range, dict)
      else:
          ref_range = {}
  
      ref_cols = {}
      counter = seed
      # Iterate over columns
      for c in data:
          if c in ref_range.keys():
              # logging.info("Using provided reference range for {}".format(c))
              if ref_range[c]["is_binary"]:
                  ref_cols[c] = rng.choice([0, 1], n)
              else:
                  ref_cols[c] = rng.uniform(
                      low=ref_range[c]["min"],
                      high=ref_range[c]["max"],
                      size=(n, 1),
                  ).ravel()
          else:
              # number of unique values
              valUniq = data[c].nunique()
  
              # Constant column
              if valUniq < 2:
                  ref_cols[c] = np.array([data[c].values[0]] * n)
  
              # Binary column
              elif (
                  valUniq == 2
                  or (c in cat_cols)
                  or (data[c].dtype == "object")
              ):
                  cs = data[c].unique()
                  ref_cols[c] = rng.choice(cs, n)
  
              # Ordinal column (seed = counter so not correlated)
              elif np.issubdtype(
                  data[c].dtype, np.dtype(int).type
              ) | np.issubdtype(data[c].dtype, np.dtype(float).type):
                  ref_cols[c] = sampleUnif(
                      data[[c]].values, n, seed=counter
                  ).ravel()
                  if counter is not None:
                      counter += 1
  
      return pd.DataFrame(ref_cols)
  
imports: from typing import Dict, List, Optional, Union
  import numpy
  import pandas
label_desc: Use image node_id 2 for calling a global function with example usage: sample_reference(x, n, cat_cols, seed, ref_range) and returns: pd