code: def to_label_prediction_example_weight(
      inputs: metric_types.StandardMetricInputs,
      eval_config: Optional[config_pb2.EvalConfig] = None,
      model_name: str = "",
      output_name: str = "",
      sub_key: Optional[metric_types.SubKey] = None,
      aggregation_type: Optional[metric_types.AggregationType] = None,
      class_weights: Optional[Dict[int, float]] = None,
      example_weighted: bool = False,
      fractional_labels: bool = False,
      flatten: bool = True,
      squeeze: bool = True,
      allow_none: bool = False,
      require_single_example_weight: bool = False,
  ) -> Iterator[Tuple[np.ndarray, np.ndarray, np.ndarray]]:
      """Yields label, prediction, and example weights for use in calculations.
  
      Where applicable this function will perform model and output name lookups as
      well as any required class ID, top K, etc conversions. It will also apply
      prediction keys and label vocabularies given the necessary information is
      provided as part of the EvalConfig (or standard estimator based naming is
      used). The sparseness of labels will be inferred from the shapes of the labels
      and predictions (i.e. if the shapes are different then the labels will be
      assumed to be sparse).
  
      If successful, the final output of calling this function will be a tuple of
      numpy arrays representing the label, prediction, and example weight
      respectively. Labels and predictions will be returned in the same shape
      provided (default behavior) unless (1) flatten is True in which case a series
      of values (one per class ID) will be returned with last dimension of size 1 or
      (2) a sub_key is used in which case the last dimension may be re-shaped to
      match the new number of outputs (1 for class_id or k, top_k for top k with
      aggregation).
  
      Note that for top_k without aggregation, the non-top_k prediction values will
      be set to float('-inf'), but for top_k with aggregation the values will be
      truncated to only return the top k values.
  
      Examples:
  
        # default behavior
        #
        # Binary classification
        Input  : labels=[1] predictions=[0.6]
        Output : (np.array([1]), np.array([0.6]), np.array([1.0]))
        # Multi-class classification w/ sparse labels
        Input : labels=[2] predictions=[0.3, 0.6, 0.1]
        Output: (np.array([2]), np.array([0.3, 0.6, 0.1]), np.array([1.0]))
        # Multi-class / multi-label classification w/ dense labels
        Input  : labels=[0, 1, 1] predictions=[0.3, 0.6, 0.1]
        Output : (np.array([0, 1, 1]), np.array([0.3, 0.6, 0.1]), np.array([1.0]))
  
        # flatten=True
        #
        # Multi-class classification w/ sparse labels
        Input  : labels=[2], predictions=[0.3, 0.6, 0.1]
        Output : (np.array([0]), np.array([0.3]), np.array([1.0])),
                 (np.array([0]), np.array([0.6]), np.array([1.0])),
                 (np.array([1]), np.array([0.1]), np.array([1.0]))
        # Multi-class/multi-label classification w/ dense labels
        Input  : labels=[0, 0, 1], predictions=[0.3, 0.6, 0.1]
        Output : (np.array([0]), np.array([0.3]), np.array([1.0])),
                 (np.array([0]), np.array([0.6]), np.array([1.0])),
                 (np.array([1]), np.array([0.1]), np.array([1.0]))
  
        # sub_key.class_id=[2]
        #
        # Multi-class classification w/ sparse labels
        Input  : labels=[2] predictions=[0.3, 0.6, 0.1]
        Output : (np.array([1]), np.array([0.1]), np.array([1.0]))
        # Multi-class classification w/ dense labels
        Input  : labels=[0, 0, 1] predictions=[0.3, 0.6, 0.1]
        Output : (np.array([1]), np.array([0.1]), np.array([1.0]))
  
        # sub_key.top_k=2 and aggregation_type is None (i.e. binarization of top 2).
        #
        # Multi-class classification w/ sparse labels
        Input  : labels=[2] predictions=[0.3, 0.6, 0.1]
        Output : (np.array([0, 0, 1]), np.array([0.3, 0.6, -inf]), np.array([1.0]))
        # Multi-class classification w/ dense labels
        Input  : labels=[0, 0, 1] predictions=[0.3, 0.1, 0.6]
        Output : (np.array([0, 0, 1]), np.array([0.3, -inf, 0.6]), np.array([1.0]))
  
        # sub_key.top_k=2 and aggregation_type is not None (i.e. aggregate top 2).
        #
        # Multi-class classification w/ sparse labels
        Input  : labels=[2] predictions=[0.3, 0.6, 0.1]
        Output : (np.array([0, 1]), np.array([0.3, 0.6]), np.array([1.0]))
        # Multi-class classification w/ dense labels
        Input  : labels=[0, 0, 1] predictions=[0.3, 0.1, 0.6]
        Output : (np.array([0, 0]), np.array([0.3, 0.6]), np.array([1.0]))
  
        # sub_key.k=2 (i.e. binarization by choosing 2nd largest predicted value).
        #
        # Multi-class classification w/ sparse labels
        Input  : labels=[0] predictions=[0.3, 0.6, 0.1]
        Output : (np.array([1]), np.array([0.3]), np.array([1.0]))
        # Multi-class classification w/ dense labels
        Input  : labels=[0] predictions=[0.3]
        Output : (np.array([0]), np.array([0.3]), np.array([1.0]))
  
      Args:
        inputs: Standard metric inputs.
        eval_config: Eval config
        model_name: Optional model name (if multi-model evaluation).
        output_name: Optional output name (if multi-output model type).
        sub_key: Optional sub key.
        aggregation_type: Optional aggregation type.
        class_weights: Optional class weights to apply to multi-class / multi-label
          labels and predictions. If used, flatten must also be True.
        example_weighted: True if example weights should be applied.
        fractional_labels: If true, each incoming tuple of (label, prediction, and
          example weight) will be split into two tuples as follows (where l, p, w
          represent the resulting label, prediction, and example weight values): (1)
          l = 0.0, p = prediction, and w = example_weight * (1.0 - label) (2) l =
          1.0, p = prediction, and w = example_weight * label If enabled, an
          exception will be raised if labels are not within [0, 1]. The
          implementation is such that tuples associated with a weight of zero are
          not yielded. This means it is safe to enable fractional_labels even when
          the labels only take on the values of 0.0 or 1.0.
        flatten: True to flatten the final label and prediction outputs so that the
          yielded values are always arrays of size 1. For example, multi-class /
          multi-label outputs would be converted into label and prediction pairs
          that could then be processed by a binary classification metric in order to
          compute a micro average over all classes. If the example weight is not a
          scalar, then they will be flattened as well, otherwise the same example
          weight value will be output for each pair of labels and predictions.
        squeeze: True to squeeze any outputs that have rank > 1. This transforms
          outputs such as np.array([[1]]) to np.array([1]).
        allow_none: True to allow labels or predictions with None values to be
          returned. When used, the values will be returned as empty np.ndarrays. The
          example weight will always be non-empty.
        require_single_example_weight: True to require that the example_weight be a
          single value.
  
      Yields:
        Tuple of (label, prediction, example_weight).
      """
  
      def fn_call_str():
          return (
              f"to_label_prediction_example_weight(inputs={inputs}, "
              f"eval_config={eval_config}, model_name={model_name}, "
              f"output_name={output_name}, sub_key={sub_key}, "
              f"aggregation_type={aggregation_type}, "
              f"class_weights={class_weights}, "
              f"fractional_labels={fractional_labels}, flatten={flatten}, "
              f"squeeze={squeeze}, allow_none={allow_none})"
          )
  
      def optionally_get_by_keys(value: Any, keys: List[str]) -> Any:
          class NotFound(object):
              pass
  
          if isinstance(value, Mapping):
              new_value = util.get_by_keys(
                  value, keys, default_value=NotFound()
              )
              if not isinstance(new_value, NotFound):
                  # Might be None if that's what is in the dict
                  return new_value
          return value
  
      try:
          prediction_key = ""
          label_key = ""
          if eval_config and eval_config.model_specs:
              for spec in eval_config.model_specs:
                  # To maintain consistency between settings where single models are used,
                  # always use '' as the model name regardless of whether a name is passed
                  spec_name = (
                      spec.name
                      if len(eval_config.model_specs) > 1
                      else ""
                  )
                  if spec_name == model_name:
                      prediction_key = spec.prediction_key
                      label_key = spec.label_key
                      break
  
          label = inputs.label
          if label_key:
              # This is to support a custom EvalSavedModel where the labels are a dict
              # but the keys are not output_names.
              label = optionally_get_by_keys(label, [label_key])
          prediction = inputs.prediction
          example_weight = inputs.example_weight
          if model_name:
              if prediction is not None:
                  prediction = util.get_by_keys(
                      prediction, [model_name]
                  )
              # Labels and weights can optionally be keyed by model name.
              label = optionally_get_by_keys(label, [model_name])
              example_weight = optionally_get_by_keys(
                  example_weight, [model_name]
              )
          if output_name:
              if prediction is not None:
                  prediction = util.get_by_keys(
                      prediction, [output_name]
                  )
              # Labels and example weights can optionally be keyed by output name.
              label = optionally_get_by_keys(label, [output_name])
              example_weight = optionally_get_by_keys(
                  example_weight, [output_name]
              )
  
          if not example_weighted or example_weight is None:
              example_weight = np.array(
                  1.0, dtype=np.float32
              )  # tf-ranking needs float32
  
          if isinstance(label, Mapping):
              raise ValueError(
                  "unable to prepare label for metric computation because the label is "
                  "a dict with unrecognized keys. If a multi-output model was used "
                  f"check that an output name was provided in all the relevant "
                  "settings (ModelSpec.label_keys, MetricsSpec.output_names, etc): "
                  f"label={label}, output_name={output_name}"
              )
          if isinstance(example_weight, Mapping):
              raise ValueError(
                  "unable to prepare example_weight for metric computation because the "
                  "example_weight is a dict with unrecognized keys. If a multi-output "
                  "model was used check that an output name was provided in all the "
                  "relevant settings (ModelSpec.example_weight_keys, "
                  f"MetricsSpec.output_names, etc): example_weight={example_weight}, "
                  f"output_name={output_name}"
              )
  
          label, prediction = prepare_labels_and_predictions(
              label, prediction, prediction_key
          )
  
          if not allow_none:
              for txt, value in zip(
                  ("label", "prediction"), (label, prediction)
              ):
                  if value is None:
                      raise ValueError(
                          f"no value provided for {txt}\n\n"
                          "This may be caused by a configuration error (i.e. label, "
                          "and/or prediction keys were not specified) or an "
                          "error in the pipeline."
                      )
  
          example_weight = util.to_numpy(example_weight)
          if require_single_example_weight and example_weight.size > 1:
              example_weight = example_weight.flatten()
              if not np.all(example_weight == example_weight[0]):
                  raise ValueError(
                      "if example_weight size > 0, the values must all be the same: "
                      f"example_weight={example_weight}\n\n"
                      "This is most likely a configuration error."
                  )
              example_weight = np.array(example_weight[0])
  
          if (
              sub_key is not None
              and label is not None
              and prediction is not None
          ):
              if sub_key.k is not None:
                  indices = top_k_indices(sub_key.k, prediction)
                  if len(prediction.shape) == 1:
                      indices = indices[0]  # 1D
                  else:
                      # 2D, take kth values
                      indices = (
                          indices[0][0 :: sub_key.k],
                          indices[1][0 :: sub_key.k],
                      )
                  if label.shape != prediction.shape:
                      label = one_hot(label, prediction)
                  label = select_indices(label, indices)
                  prediction = select_indices(prediction, indices)
              else:
                  if sub_key.top_k is not None:
                      # Set all non-top-k predictions to -inf. Note that we do not sort.
                      indices = top_k_indices(sub_key.top_k, prediction)
                      if aggregation_type is None:
                          top_k_predictions = np.full(
                              prediction.shape, float("-inf")
                          )
                          top_k_predictions[indices] = prediction[
                              indices
                          ]
                          prediction = top_k_predictions
                      else:
                          if label.shape != prediction.shape:
                              label = one_hot(label, prediction)
                          label = select_indices(label, indices)
                          prediction = select_indices(
                              prediction, indices
                          )
                  if sub_key.class_id is not None:
                      label, prediction = select_class_id(
                          sub_key.class_id, label, prediction
                      )
  
          # For consistency, make sure all outputs are arrays (i.e. convert scalars)
          if label is not None and not label.shape:
              label = label.reshape((1,))
          if prediction is not None and not prediction.shape:
              prediction = prediction.reshape((1,))
          if not example_weight.shape:
              example_weight = example_weight.reshape((1,))
  
          label = label if label is not None else np.array([])
          prediction = (
              prediction if prediction is not None else np.array([])
          )
  
          flatten_size = prediction.size or label.size
          if flatten:
              if example_weight.size == 1:
                  example_weight = np.array(
                      [
                          float(example_weight)
                          for i in range(flatten_size)
                      ]
                  )
              elif example_weight.size != flatten_size:
                  raise ValueError(
                      "example_weight size does not match the size of labels and "
                      "predictions: label={}, prediction={}, example_weight={}".format(
                          label, prediction, example_weight
                      )
                  )
  
          if class_weights:
              if not flatten:
                  raise ValueError(
                      "class_weights can only be used when flatten is also used: "
                      f"class_weights={class_weights}, flatten={flatten}\n\n"
                      "This is likely caused by a configuration error (i.e. micro "
                      "averaging being applied to metrics that don't support micro "
                      "averaging"
                  )
              example_weight = np.array(
                  [
                      example_weight[i] * class_weights[i]
                      if i in class_weights
                      else 0.0
                      for i in range(flatten_size)
                  ]
              )
  
          def yield_results(label, prediction, example_weight):
              if (
                  not flatten
                  or (label.size == 0 and prediction.size == 0)
                  or (
                      label.size == 1
                      and prediction.size == 1
                      and example_weight.size == 1
                  )
              ):
                  if squeeze:
                      yield _squeeze(label), _squeeze(
                          prediction
                      ), _squeeze(example_weight)
                  else:
                      yield label, prediction, example_weight
              elif label.size == 0:
                  for p, w in zip(
                      prediction.flatten(), example_weight.flatten()
                  ):
                      yield label, np.array([p]), np.array([w])
              elif prediction.size == 0:
                  for l, w in zip(
                      label.flatten(), example_weight.flatten()
                  ):
                      yield np.array([l]), prediction, np.array([w])
              elif (
                  label.size == prediction.size
                  and label.size == example_weight.size
              ):
                  for l, p, w in zip(
                      label.flatten(),
                      prediction.flatten(),
                      example_weight.flatten(),
                  ):
                      yield np.array([l]), np.array([p]), np.array([w])
              elif (
                  label.shape[-1] == 1
                  and prediction.size == example_weight.size
              ):
                  label = one_hot(label, prediction)
                  for l, p, w in zip(
                      label.flatten(),
                      prediction.flatten(),
                      example_weight.flatten(),
                  ):
                      yield np.array([l]), np.array([p]), np.array([w])
              else:
                  raise ValueError(
                      "unable to pair labels, predictions, and example weights: "
                      f"label={label}, prediction={prediction}, "
                      f"example_weight={example_weight}\n\n"
                      "This is most likely a configuration error."
                  )
  
          for result in yield_results(
              label, prediction, example_weight
          ):
              if fractional_labels and label.size:
                  for new_result in _yield_fractional_labels(*result):
                      yield new_result
              else:
                  yield result
      except Exception as e:
          import sys  # pylint: disable=g-import-not-at-top
  
          raise type(e)(str(e) + f"\n\n{fn_call_str()}").with_traceback(
              sys.exc_info()[2]
          )
  
imports: import inspect
  import math
  from typing import Any, Callable, Dict, Iterable, Iterator, List, Mapping, Optional, Tuple, Union
  import numpy
  import tensorflow
  from tensorflow_model_analysis import constants
  from tensorflow_model_analysis.api import types
  from tensorflow_model_analysis.metrics import metric_types
  from tensorflow_model_analysis.proto import config_pb2
  from tensorflow_model_analysis.utils import util
  from tensorflow_metadata.proto.v0 import schema_pb2
label_desc: Use image node_id 17 for calling a global function with example usage: to_label_prediction_example_weight(inputs, eval_config, model_name, output_name, sub_key, aggregation_type, class_weights, example_weighted, fractional_labels, flatten, squeeze, allow_none, require_single_example_weight) and returns: str, inputs, str, eval_config, str, model_name, str, output_name, str, sub_key, str, aggregation_type, str, class_weights, str, fractional_labels, str, flatten, str, squeeze, str, allow_none, str, value, new_value