code: def _scale_by_min_max_internal(
      x: common_types.ConsistentTensorType,
      key: Optional[common_types.TensorType],
      output_min: float,
      output_max: float,
      elementwise: bool,
      key_vocabulary_filename: Optional[str] = None,
  ) -> common_types.ConsistentTensorType:
      """Implementation for scale_by_min_max."""
      if output_min >= output_max:
          raise ValueError("output_min must be less than output_max")
  
      x = tf.cast(x, tf.float32)
      if key is None:
          (
              min_x_value,
              max_x_value,
          ) = analyzers._min_and_max(  # pylint: disable=protected-access
              x, reduce_instance_dims=not elementwise
          )
      else:
          if elementwise and isinstance(
              x, (tf.SparseTensor, tf.RaggedTensor)
          ):
              raise NotImplementedError(
                  "Per-key elementwise reduction of Composite Tensors not supported"
              )
          key_values = analyzers._min_and_max_per_key(  # pylint: disable=protected-access
              x,
              key,
              reduce_instance_dims=not elementwise,
              key_vocabulary_filename=key_vocabulary_filename,
          )
          if key_vocabulary_filename is None:
              key_vocab, min_x_value, max_x_value = key_values
              # Missing keys will translate to 0 for both min and max which will be
              # ignored below in the tf.where.
              (
                  min_x_value,
                  max_x_value,
              ) = tf_utils.map_per_key_reductions(
                  (min_x_value, max_x_value),
                  key,
                  key_vocab,
                  x,
                  not elementwise,
              )
          else:
              if elementwise:
                  raise NotImplementedError(
                      "Elementwise scaling does not support key_vocabulary_filename"
                  )
              minus_min_max_for_key = tf_utils.apply_per_key_vocabulary(
                  key_values, key, target_ndims=x.get_shape().ndims
              )
              min_x_value, max_x_value = (
                  -minus_min_max_for_key[:, 0],
                  minus_min_max_for_key[:, 1],
              )
  
      compose_result_fn = _make_composite_tensor_wrapper_if_composite(x)
      x_values = tf_utils.get_values(x)
      if isinstance(x, tf.SparseTensor):
          if elementwise:
              min_x_value = tf.gather_nd(
                  tf.broadcast_to(min_x_value, x.dense_shape), x.indices
              )
              max_x_value = tf.gather_nd(
                  tf.broadcast_to(max_x_value, x.dense_shape), x.indices
              )
      elif isinstance(x, tf.RaggedTensor):
          if elementwise:
              raise NotImplementedError(
                  "Elementwise min_and_max does not support RaggedTensors."
              )
  
      # If min>=max, then the corresponding input to the min_and_max analyzer either
      # was empty and the analyzer returned default values, or contained only one
      # distinct value. In this case we scale x by applying a sigmoid function which
      # is continuous, increasing and maps (-inf, inf) -> (0, 1). Its output is
      # then projected on the requested range. Note that both the options of
      # tf.where are computed, which means that this will compute unused NaNs.
      numerator = tf.cast(x_values, min_x_value.dtype) - min_x_value
      where_cond = min_x_value < max_x_value
      where_cond = tf.cast(
          tf.zeros_like(numerator)
          + tf.cast(where_cond, numerator.dtype),
          dtype=tf.bool,
      )
      scaled_result = tf.where(
          where_cond,
          numerator / (max_x_value - min_x_value),
          tf.math.sigmoid(x_values),
      )
  
      return compose_result_fn(
          (scaled_result * (output_max - output_min)) + output_min
      )
  
imports: import os
  from typing import Any, Callable, Iterable, Optional, Tuple, Union
  import tensorflow
  from tensorflow_transform import analyzers
  from tensorflow_transform import common
  from tensorflow_transform import common_types
  from tensorflow_transform import gaussianization
  from tensorflow_transform import schema_inference
  from tensorflow_transform import tf_utils
  from tfx_bsl.types import tfx_namedtuple
label_desc: Use image node_id 7 for calling a global function with example usage: _scale_by_min_max_internal(x, key, output_min, output_max, elementwise, key_vocabulary_filename) and returns: compose_result_fn