code: def get_p_groups(
      self,
      first_names: pd.Series = None,
      last_names: pd.Series = None,
      zip_codes: pd.Series = None,
      detect_gender_bias: bool = True,
      detect_race_bias: bool = True,
  ) -> pd.DataFrame:
      if (
          first_names is None
          and last_names is None
          and zip_codes is None
      ):
          raise ValueError(
              "first_names/last_names/zip_codes must be provided"
          )
      if not self.__is_same_length(
          [first_names, last_names, zip_codes]
      ):
          raise ValueError("Input data has different lengths")
      first_names = self.to_series(first_names, "first_name", str)
      last_names = self.to_series(last_names, "last_name", str)
      zip_codes = self.to_series(zip_codes, "zip_code", str)
      user_data_count = self.__get_user_data_count(
          [first_names, last_names, zip_codes]
      )
      p_groups = pd.DataFrame(index=list(range(user_data_count)))
      if first_names is not None:
          first_names = first_names.str.upper()
          first_names = first_names.str.replace(r"\s+", "")
      if last_names is not None:
          last_names = last_names.str.upper()
          last_names = last_names.str.replace(r"\s+", "")
      if zip_codes is not None:
          zip_codes = zip_codes.str.slice(0, 5)
          zip_codes = zip_codes.str.zfill(5)
          zip_codes.loc[~zip_codes.str.match(r"\d{5}")] = ""
      empty_series = pd.Series(np.empty(user_data_count, str))
      if first_names is None:
          first_names = empty_series.rename("first_name")
      if last_names is None:
          last_names = empty_series.rename("last_name")
      if zip_codes is None:
          zip_codes = empty_series.rename("zip_code")
      if detect_gender_bias:
          gender_probabilities = first_names.to_frame().join(
              p_gender_given_first_name_df, on="first_name"
          )[p_gender_given_first_name_df.columns]
          p_groups = p_groups.join(gender_probabilities)
      if detect_race_bias:
          model_first_names = p_first_name_given_race_df.index
          model_last_names = (
              self.last_name_model._PROB_RACE_GIVEN_SURNAME.index
          )
          model_zip_codes = (
              self.last_name_zip_code_model._PROB_ZCTA_GIVEN_RACE.index
          )
          first_names_in_model = first_names.isin(model_first_names)
          last_names_in_model = last_names.isin(model_last_names)
          zip_codes_in_model = zip_codes.isin(model_zip_codes)
          first_names.loc[~first_names_in_model] = ""
          last_names.loc[~last_names_in_model] = ""
          zip_codes.loc[~zip_codes_in_model] = ""
          first_names_rows = first_names.str.len() > 0
          last_names_rows = last_names.str.len() > 0
          zip_codes_rows = zip_codes.str.len() > 0
          only_first_names_rows = (
              first_names_rows & ~last_names_rows & ~zip_codes_rows
          )
          only_last_names_rows = (
              ~first_names_rows & last_names_rows & ~zip_codes_rows
          )
          only_zip_codes_rows = (
              ~first_names_rows & ~last_names_rows & zip_codes_rows
          )
          full_name_rows = (
              first_names_rows & last_names_rows & ~zip_codes_rows
          )
          first_name_zip_code_rows = (
              first_names_rows & ~last_names_rows & zip_codes_rows
          )
          last_name_zip_code_rows = (
              ~first_names_rows & last_names_rows & zip_codes_rows
          )
          full_name_zip_code_rows = (
              first_names_rows & last_names_rows & zip_codes_rows
          )
          first_names_probabilities = (
              self.first_name_model.get_probabilities(
                  first_names.loc[only_first_names_rows].reset_index(
                      drop=True
                  )
              )[races].set_index(
                  only_first_names_rows[only_first_names_rows].index
              )
          )
          last_names_probabilities = (
              self.last_name_model.get_probabilities(
                  last_names.loc[only_last_names_rows].reset_index(
                      drop=True
                  )
              )[races].set_index(
                  only_last_names_rows[only_last_names_rows].index
              )
          )
          zip_codes_probabilities = (
              self.zip_code_model.get_probabilities(
                  zip_codes.loc[only_zip_codes_rows].reset_index(
                      drop=True
                  )
              )[races].set_index(
                  only_zip_codes_rows[only_zip_codes_rows].index
              )
          )
          full_name_probabilities = (
              self.full_name_model.get_probabilities(
                  first_names.loc[full_name_rows].reset_index(
                      drop=True
                  ),
                  last_names.loc[full_name_rows].reset_index(drop=True),
              )[races].set_index(full_name_rows[full_name_rows].index)
          )
          first_name_zip_code_probabilities = (
              self.first_name_zip_code_model.get_probabilities(
                  first_names.loc[first_name_zip_code_rows].reset_index(
                      drop=True
                  ),
                  zip_codes.loc[first_name_zip_code_rows].reset_index(
                      drop=True
                  ),
              )[races].set_index(
                  first_name_zip_code_rows[
                      first_name_zip_code_rows
                  ].index
              )
          )
          last_name_zip_code_probabilities = (
              self.last_name_zip_code_model.get_probabilities(
                  last_names.loc[last_name_zip_code_rows].reset_index(
                      drop=True
                  ),
                  zip_codes.loc[last_name_zip_code_rows].reset_index(
                      drop=True
                  ),
              )[races].set_index(
                  last_name_zip_code_rows[last_name_zip_code_rows].index
              )
          )
          full_name_zip_code_probabilities = (
              self.full_name_zip_code_model.get_probabilities(
                  first_names.loc[full_name_zip_code_rows].reset_index(
                      drop=True
                  ),
                  last_names.loc[full_name_zip_code_rows].reset_index(
                      drop=True
                  ),
                  zip_codes.loc[full_name_zip_code_rows].reset_index(
                      drop=True
                  ),
              )[races].set_index(
                  full_name_zip_code_rows[full_name_zip_code_rows].index
              )
          )
          p_groups.loc[
              only_first_names_rows, races
          ] = first_names_probabilities
          p_groups.loc[
              only_last_names_rows, races
          ] = last_names_probabilities
          p_groups.loc[
              only_zip_codes_rows, races
          ] = zip_codes_probabilities
          p_groups.loc[full_name_rows, races] = full_name_probabilities
          p_groups.loc[
              first_name_zip_code_rows, races
          ] = first_name_zip_code_probabilities
          p_groups.loc[
              last_name_zip_code_rows, races
          ] = last_name_zip_code_probabilities
          p_groups.loc[
              full_name_zip_code_rows, races
          ] = full_name_zip_code_probabilities
      p_groups.fillna(0.0, inplace=True)
      return p_groups
  
imports: from bias_detector.BiasMetric import BiasMetric
  from bias_detector.BiasReport import BiasReport
  from bias_detector.models.FirstNameModel import FirstNameModel
  from bias_detector.models.FirstNameZipcodeModel import FirstNameZipcodeModel
  from bias_detector.models.FullNameModel import FullNameModel
  from bias_detector.models.FullNameZipcodeModel import FullNameZipcodeModel
  from bias_detector.bias_metrics.BiasMetricImpl import BiasMetricImpl
  from bias_detector.bias_metrics.BiasMetricInput import BiasMetricInput
  from bias_detector.bias_metrics.FprDiff import FprDiff
  from bias_detector.bias_metrics.PositivePredProbDiff import PositivePredProbDiff
  from bias_detector.bias_metrics.TprDiff import TprDiff
  from bias_detector.common import *
  import surgeo
label_desc: Use image node_id 7 for calling the BiasDetector obj's underlying member method code with example usage: obj.get_p_groups(first_names, last_names, zip_codes, detect_gender_bias, detect_race_bias) and returns: p_groups