class_docstr: Pickier version of MetricFrame.
  
  This holds the internal result from a disaggregated metric
  computation, and provides `apply_grouping()` (to cover min
  and max), `difference()` and `ratio()` methods.
  
  The main difference to the results computed by MetricFrame
  is that no account is made of whether the user supplied
  a bare function or a dictionary. Hence the results are
  always Series or DataFrame.
  
  Parameters
  ----------
  overall: Series or DataFrame
      The metric function(s) computed on the entire dataset, split by
      control features if supplied
  by_group: Series or DataFrame
      The metric function(s) computed on each subgroup identified by
      the sensitive and control features
class_docstr_tok: ["Pickier","version","of","MetricFrame",".","This","holds","the","internal","result","from","a","disaggregated","metric","computation",",","and","provides","`","apply_grouping","(",")","`","(","to","cover","min","and","max",")",",","`","difference","(",")","`","and","`","ratio","(",")","`","methods",".","The","main","difference","to","the","results","computed","by","MetricFrame","is","that","no","account","is","made","of","whether","the","user","supplied","a","bare","function","or","a","dictionary",".","Hence","the","results","are","always","Series","or","DataFrame",".","Parameters","--","--","--","--","--","overall",":","Series","or","DataFrame","The","metric","function","(","s",")","computed","on","the","entire","dataset",",","split","by","control","features","if","supplied","by_group",":","Series","or","DataFrame","The","metric","function","(","s",")","computed","on","each","subgroup","identified","by","the","sensitive","and","control","features"]
docstr: Compute mins or maxes.
  
  Parameters
  ----------
  grouping_function: string
      Must be 'min' or 'max'
  control_feature_names: Optional[List[str]]
      Names of the control features. Must appear in the index of the `overall`
      and `by_group` properties
  errors: string {'raise', 'coerce'}, default 'raise'
      How to deal with any errors. Either coerce to `np.nan` or wrap the
      exception and reraise
  
  Returns
  -------
  Series or DataFrame
      Contains the desired mins or maxes
docstr_tok: ["Compute","mins","or","maxes",".","Parameters","--","--","--","--","--","grouping_function",":","string","Must","be","'min","'","or","'max'","control_feature_names",":","Optional","[","List","[","str","]","]","Names","of","the","control","features",".","Must","appear","in","the","index","of","the","`","overall","`","and","`","by_group","`","properties","errors",":","string","{","'raise","'",",","'coerce","'","}",",","default","'raise'","How","to","deal","with","any","errors",".","Either","coerce","to","`","np.nan","`","or","wrap","the","exception","and","reraise","Returns","--","--","--","-","Series","or","DataFrame","Contains","the","desired","mins","or","maxes"]
code: def apply_grouping(
      self,
      grouping_function: str,
      control_feature_names: Optional[List[str]] = None,
      errors: str = "raise",
  ) -> Union[pd.Series, pd.DataFrame]:
      """Compute mins or maxes.
  
      Parameters
      ----------
      grouping_function: string
          Must be 'min' or 'max'
      control_feature_names: Optional[List[str]]
          Names of the control features. Must appear in the index of the `overall`
          and `by_group` properties
      errors: string {'raise', 'coerce'}, default 'raise'
          How to deal with any errors. Either coerce to `np.nan` or wrap the
          exception and reraise
  
      Returns
      -------
      Series or DataFrame
          Contains the desired mins or maxes
      """
      if grouping_function not in _VALID_GROUPING_FUNCTION:
          raise ValueError(_INVALID_GROUPING_FUNCTION_ERROR_MESSAGE)
  
      if errors not in _VALID_ERROR_STRING:
          raise ValueError(_INVALID_ERRORS_VALUE_ERROR_MESSAGE)
  
      if not control_feature_names:
          if errors == "raise":
              try:
                  mf = self.by_group
                  if grouping_function == "min":
                      vals = [mf[m].min() for m in mf.columns]
                  else:
                      vals = [mf[m].max() for m in mf.columns]
  
                  result = pd.Series(
                      vals, index=self.by_group.columns, dtype="object"
                  )
              except ValueError as ve:
                  raise ValueError(
                      _MF_CONTAINS_NON_SCALAR_ERROR_MESSAGE
                  ) from ve
          elif errors == "coerce":
              if not control_feature_names:
                  mf = self.by_group
                  # Fill in the possible min/max values, else np.nan
                  if grouping_function == "min":
                      vals = [
                          mf[m].min()
                          if np.isscalar(mf[m].values[0])
                          else np.nan
                          for m in mf.columns
                      ]
                  else:
                      vals = [
                          mf[m].max()
                          if np.isscalar(mf[m].values[0])
                          else np.nan
                          for m in mf.columns
                      ]
  
                  result = pd.Series(
                      vals, index=mf.columns, dtype="object"
                  )
      else:
          if errors == "raise":
              try:
                  if grouping_function == "min":
                      result = self.by_group.groupby(
                          level=control_feature_names
                      ).min()
                  else:
                      result = self.by_group.groupby(
                          level=control_feature_names
                      ).max()
              except ValueError as ve:
                  raise ValueError(
                      _MF_CONTAINS_NON_SCALAR_ERROR_MESSAGE
                  ) from ve
          elif errors == "coerce":
              # Fill all impossible columns with NaN before grouping metric frame
              mf = self.by_group.copy()
              mf = mf.apply(
                  lambda x: x.apply(
                      lambda y: y if np.isscalar(y) else np.nan
                  )
              )
              if grouping_function == "min":
                  result = mf.groupby(level=control_feature_names).min()
              else:
                  result = mf.groupby(level=control_feature_names).max()
  
      assert isinstance(result, pd.Series) or isinstance(
          result, pd.DataFrame
      )
  
      return result
  
file_path: fairlearn/fairlearn/metrics/_disaggregated_result.py
imports: import logging
  from typing import Dict, List, Optional, Union
  import numpy
  import pandas
  from ._annotated_metric_function import AnnotatedMetricFunction
label_desc: Use image node_id 4 for calling the DisaggregatedResult obj's underlying member method code with example usage: obj.apply_grouping(grouping_function, control_feature_names, errors) and returns: result