code: def _get_annotator_stats(
      labels_multiannotator: np.ndarray,
      pred_probs: np.ndarray,
      consensus_label: np.ndarray,
      num_annotations: np.ndarray,
      annotator_agreement: np.ndarray,
      model_weight: np.ndarray,
      annotator_weight: np.ndarray,
      consensus_quality_score: np.ndarray,
      detailed_label_quality: Optional[np.ndarray] = None,
      annotator_ids: Optional[pd.Index] = None,
      quality_method: str = "crowdlab",
  ) -> pd.DataFrame:
      """Returns a dictionary containing overall statistics about each annotator.
  
      Parameters
      ----------
      labels_multiannotator : np.ndarray
          2D numpy array of multiple given labels for each example with shape ``(N, M)``,
          where N is the number of examples and M is the number of annotators.
          For more details, labels in the same format expected by the `~cleanlab.multiannotator.get_label_quality_multiannotator`.
      pred_probs : np.ndarray
          An array of shape ``(N, K)`` of model-predicted probabilities, ``P(label=k|x)``.
          For details, predicted probabilities in the same format expected by the `~cleanlab.multiannotator.get_label_quality_multiannotator`.
      consensus_label : np.ndarray
          An array of shape ``(N,)`` with the consensus labels aggregated from all annotators.
      num_annotations : np.ndarray
          An array of shape ``(N,)`` with the number of annotators that have labeled each example.
      annotator_agreement : np.ndarray
          An array of shape ``(N,)`` with the fraction of annotators that agree with each consensus label.
      model_weight : float
          float specifying the model weight used in weighted averages,
          None if model weight is not used to compute quality scores
      annotator_weight : np.ndarray
          An array of shape ``(M,)`` where M is the number of annotators, specifying the annotator weights used in weighted averages,
          None if annotator weights are not used to compute quality scores
      consensus_quality_score : np.ndarray
          An array of shape ``(N,)`` with the quality score of the consensus.
      detailed_label_quality :
          pandas DataFrame containing the detailed label quality scores for all examples and annotators
      quality_method : str, default = "crowdlab" (Options: ["crowdlab", "agreement"])
          Specifies the method used to calculate the quality of the consensus label.
          For valid quality methods, view `~cleanlab.multiannotator.get_label_quality_multiannotator`
  
      Returns
      -------
      annotator_stats : pd.DataFrame
          Overall statistics about each annotator.
          For details, see the documentation of `~cleanlab.multiannotator.get_label_quality_multiannotator`.
      """
  
      annotator_quality = _get_annotator_quality(
          labels_multiannotator=labels_multiannotator,
          pred_probs=pred_probs,
          consensus_label=consensus_label,
          num_annotations=num_annotations,
          annotator_agreement=annotator_agreement,
          model_weight=model_weight,
          annotator_weight=annotator_weight,
          detailed_label_quality=detailed_label_quality,
          quality_method=quality_method,
      )
  
      # Compute the number of labels labeled/ by each annotator
      num_examples_labeled = np.sum(
          ~np.isnan(labels_multiannotator), axis=0
      )
  
      # Compute the fraction of labels annotated by each annotator that agrees with the consensus label
      # TODO: check if we should drop singleton labels here
      agreement_with_consensus = np.zeros(
          labels_multiannotator.shape[1]
      )
      for i in range(len(agreement_with_consensus)):
          labels = labels_multiannotator[:, i]
          labels_mask = ~np.isnan(labels)
          agreement_with_consensus[i] = np.mean(
              labels[labels_mask] == consensus_label[labels_mask]
          )
  
      # Find the worst labeled class for each annotator
      worst_class = _get_annotator_worst_class(
          labels_multiannotator=labels_multiannotator,
          consensus_label=consensus_label,
          consensus_quality_score=consensus_quality_score,
      )
  
      # Create multi-annotator stats DataFrame from its columns
      annotator_stats = pd.DataFrame(
          {
              "annotator_quality": annotator_quality,
              "agreement_with_consensus": agreement_with_consensus,
              "worst_class": worst_class,
              "num_examples_labeled": num_examples_labeled,
          },
          index=annotator_ids,
      )
  
      return annotator_stats.sort_values(
          by=["annotator_quality", "agreement_with_consensus"]
      )
  
imports: import warnings
  import numpy
  import pandas
  from typing import List, Dict, Any, Union, Tuple, Optional
  from cleanlab.rank import get_label_quality_scores
  from cleanlab.internal.util import get_num_classes, value_counts
  from cleanlab.internal.constants import CLIPPING_LOWER_BOUND
  from cleanlab.internal.multiannotator_utils import assert_valid_inputs_multiannotator, assert_valid_pred_probs, check_consensus_label_classes, find_best_temp_scaler, temp_scale_pred_probs
label_desc: Use image node_id 8 for calling a global function with example usage: _get_annotator_stats(labels_multiannotator, pred_probs, consensus_label, num_annotations, annotator_agreement, model_weight, annotator_weight, consensus_quality_score, detailed_label_quality, annotator_ids, quality_method) and returns: annotator_stats