class_docstr: Calculates absolute metrics for a given dataframe with model scores and
  labels, divided by different values on protected attributes.
  
  Attributes
  ----------
  absolute_metrics : List[str]
      Calculated bias metrics.
  
  Methods
  -------
  get_crosstabs(df, score_thresholds=None, attr_cols=None, score_col="score", label_col="label_value")
      Calculates metrics for a given dataframe.
  get_multimodel_crosstabs(df, score_thresholds=None, attr_cols=None, score_col="score", label_col="label_value")
      Calculates metrics for a given dataframe with multiple models.
class_docstr_tok: ["Calculates","absolute","metrics","for","a","given","dataframe","with","model","scores","and","labels",",","divided","by","different","values","on","protected","attributes",".","Attributes","--","--","--","--","--","absolute_metrics",":","List","[","str","]","Calculated","bias","metrics",".","Methods","--","--","--","-","get_crosstabs","(","df",",","score_thresholds=None",",","attr_cols=None",",","score_col=","''","score","''",",","label_col=","''","label_value","''",")","Calculates","metrics","for","a","given","dataframe",".","get_multimodel_crosstabs","(","df",",","score_thresholds=None",",","attr_cols=None",",","score_col=","''","score","''",",","label_col=","''","label_value","''",")","Calculates","metrics","for","a","given","dataframe","with","multiple","models","."]
docstr:  Creates univariate groups and calculates group metrics for results
   from a single model.
  
   Parameters
   ----------
   df : pandas.DataFrame
       Results of model classification. Must contain:
       [score_column,  label_column].
   score_thresholds : Dict[str, List[Union[int, float]]]
       The possible thresholds of the model.
       Accepted keys:
           - 'rank_abs' for absolute ranking (top k scores classified as
              positive).
           - 'rank_pct' for percentage ranking (top X% classified as
              positive).
           - 'score_val' for value threshold (Scores above Y classified as
              positive).
       The values for each key represent the different tested thresholds.
       These must be inside a list.
       If not specified, it is assumed the scores are already in binary
       form.
   attr_cols: List[str]
       Columns with protected attributes. If not specified, all
       columns except 'id', 'model_id', 'entity_id', 'score', 'label_value'
       are used. The values in these columns must be categorical.
   score_col : str
       Column of the dataframe that represents classification result.
       Must be numeric / binary.
   label_col : str
       Column of the dataframe that represents label of instance.
       Values in the column must be binary.
   Returns
   -------
  Tuple[pd.DataFrame, List[str]]
       Metrics for each group in the protected attribute, each specified
       threshold. List of protected attributes.
docstr_tok: ["Creates","univariate","groups","and","calculates","group","metrics","for","results","from","a","single","model",".","Parameters","--","--","--","--","--","df",":","pandas.DataFrame","Results","of","model","classification",".","Must","contain",":","[","score_column",",","label_column","]",".","score_thresholds",":","Dict","[","str",",","List","[","Union","[","int",",","float","]","]","]","The","possible","thresholds","of","the","model",".","Accepted","keys",":","-","'rank_abs","'","for","absolute","ranking","(","top","k","scores","classified","as","positive",")",".","-","'rank_pct","'","for","percentage","ranking","(","top","X","%","classified","as","positive",")",".","-","'score_val","'","for","value","threshold","(","Scores","above","Y","classified","as","positive",")",".","The","values","for","each","key","represent","the","different","tested","thresholds",".","These","must","be","inside","a","list",".","If","not","specified",",","it","is","assumed","the","scores","are","already","in","binary","form",".","attr_cols",":","List","[","str","]","Columns","with","protected","attributes",".","If","not","specified",",","all","columns","except","'id","'",",","'model_id","'",",","'entity_id","'",",","'score","'",",","'label_value'","are","used",".","The","values","in","these","columns","must","be","categorical",".","score_col",":","str","Column","of","the","dataframe","that","represents","classification","result",".","Must","be","numeric","\/","binary",".","label_col",":","str","Column","of","the","dataframe","that","represents","label","of","instance",".","Values","in","the","column","must","be","binary",".","Returns","--","--","--","-","Tuple","[","pd.DataFrame",",","List","[","str","]","]","Metrics","for","each","group","in","the","protected","attribute",",","each","specified","threshold",".","List","of","protected","attributes","."]
code: def get_crosstabs(
      self,
      df,
      score_thresholds: Dict[str, List[Union[int, float]]] = None,
      attr_cols: List[str] = None,
      score_col: str = "score",
      label_col: str = "label_value",
  ) -> Tuple[pd.DataFrame, List[str]]:
      """
       Creates univariate groups and calculates group metrics for results
       from a single model.
  
       Parameters
       ----------
       df : pandas.DataFrame
           Results of model classification. Must contain:
           [score_column,  label_column].
       score_thresholds : Dict[str, List[Union[int, float]]]
           The possible thresholds of the model.
           Accepted keys:
               - 'rank_abs' for absolute ranking (top k scores classified as
                  positive).
               - 'rank_pct' for percentage ranking (top X% classified as
                  positive).
               - 'score_val' for value threshold (Scores above Y classified as
                  positive).
           The values for each key represent the different tested thresholds.
           These must be inside a list.
           If not specified, it is assumed the scores are already in binary
           form.
       attr_cols: List[str]
           Columns with protected attributes. If not specified, all
           columns except 'id', 'model_id', 'entity_id', 'score', 'label_value'
           are used. The values in these columns must be categorical.
       score_col : str
           Column of the dataframe that represents classification result.
           Must be numeric / binary.
       label_col : str
           Column of the dataframe that represents label of instance.
           Values in the column must be binary.
       Returns
       -------
      Tuple[pd.DataFrame, List[str]]
           Metrics for each group in the protected attribute, each specified
           threshold. List of protected attributes.
      """
      if not attr_cols:
          non_attr_cols = [
              "id",
              "model_id",
              "entity_id",
              score_col,
              label_col,
          ]
          # index of the columns that are protected attributes.
          attr_cols = list(df.columns[~df.columns.isin(non_attr_cols)])
  
      necessary_cols = attr_cols + [score_col, label_col]
      for col in ["id", "model_id", "entity_id"]:
          if col in df.columns:
              necessary_cols.append(col)
      # Copy only the necessary columns
      df = df[
          necessary_cols
      ].copy()  # To not transform original dataframe.
  
      # Validation step.
      for col in [score_col, label_col]:
          # Validate if column is in dataframe.
          if col not in df.columns:
              raise KeyError(
                  f'The column "{col}" is not on the dataframe.'
              )
      if len(df[label_col].unique()) > 2:
          raise ValueError("Labels are not binarized.")
      else:
          df[label_col] = df[label_col].astype(int)
  
      for col in attr_cols:
          # Validate if column is in dataframe.
          if col not in df.columns:
              raise KeyError(
                  f'The attribute column "{col}" is not on the dataframe.'
              )
          # Validate if column has correct datatype.
          if df[col].dtype not in (object, str):
              raise TypeError(
                  f'The attribute column "{col}" has in invalid datatype.'
              )
  
      # In case no threshold is provided.
      metrics_matrices = []
      if not score_thresholds and len(df[score_col].unique()) > 2:
          raise ValueError(
              "Scores are not binarized. Provide a threshold."
          )
      elif not score_thresholds:  # No thresholds given and binarized
          df[score_col] = df[score_col].astype(int)
          metrics_matrices.append(
              self.gen_metrics_df(
                  df, attr_cols, score_col, label_col, "binary 0/1"
              )
          )
          score_thresholds = {}
      # In case a threshold is provided.
      binarized_column = str(
          uuid.uuid4()
      )  # Add a column with binary scores.
      # This is done to maintain the score for future iterations in threshold.
      sorted_df = False  # Flag to sort the dataframe in the first run.
      for key, values in score_thresholds.items():
          for value in values:
              if not sorted_df:
                  # Sort df only once, at the first iteration.
                  df = df.sort_values(
                      score_col, ascending=False
                  ).reset_index(drop=True)
                  sorted_df = True
              # Cast scores as ints in the dataframe
              if key == "rank_abs":
                  df[binarized_column] = (df.index < value).astype(int)
              elif key == "rank_pct":
                  df[binarized_column] = (
                      df.index < value * df.shape[0]
                  ).astype(int)
              elif key == "score_val":
                  df[binarized_column] = (
                      df[score_col] >= value
                  ).astype(int)
              else:
                  raise KeyError("Invalid keys")
              metrics_matrices.append(
                  self.gen_metrics_df(
                      df,
                      attr_cols,
                      binarized_column,
                      label_col,
                      f"{value}_{key[-3:]}",
                  )
              )
      return pd.concat(metrics_matrices), attr_cols
  
file_path: aequitas/src/aequitas/group.py
imports: import logging
  import uuid
  from typing import Any, Dict, List, Tuple, Union
  from collections import OrderedDict
  import numpy
  import pandas
  from .bias import Bias
  from .plot import summary, disparity, absolute
label_desc: Use image node_id 5 for calling the Group obj's underlying member method code with example usage: obj.get_crosstabs(df, score_thresholds, attr_cols, score_col, label_col) and returns: pd,  attr_cols