code: def scale_by_min_max_per_key(
      x: common_types.ConsistentTensorType,
      key: common_types.TensorType,
      output_min: float = 0.0,
      output_max: float = 1.0,
      elementwise: bool = False,
      key_vocabulary_filename: Optional[str] = None,
      name: Optional[str] = None,
  ) -> common_types.ConsistentTensorType:
      # pyformat: disable
      """Scale a numerical column into a predefined range on a per-key basis.
  
      Args:
        x: A numeric `Tensor`, `SparseTensor`, or `RaggedTensor`.
        key: A `Tensor`, `SparseTensor`, or `RaggedTensor` of dtype tf.string.
            Must meet one of the following conditions:
            0. key is None
            1. Both x and key are dense,
            2. Both x and key are composite and `key` must exactly match `x` in
               everything except values,
            3. The axis=1 index of each x matches its index of dense key.
        output_min: The minimum of the range of output values.
        output_max: The maximum of the range of output values.
        elementwise: If true, scale each element of the tensor independently.
        key_vocabulary_filename: (Optional) The file name for the per-key file.
          If None, this combiner will assume the keys fit in memory and will not
          store the analyzer result in a file. If '', a file name will be chosen
          based on the current TensorFlow scope. If not '', it should be unique
          within a given preprocessing function.
        name: (Optional) A name for this operation.
  
      Example:
  
      >>> def preprocessing_fn(inputs):
      ...   return {
      ...      'scaled': tft.scale_by_min_max_per_key(inputs['x'], inputs['s'])
      ...   }
      >>> raw_data = [dict(x=1, s='a'), dict(x=0, s='b'), dict(x=3, s='a')]
      >>> feature_spec = dict(
      ...     x=tf.io.FixedLenFeature([], tf.float32),
      ...     s=tf.io.FixedLenFeature([], tf.string))
      >>> raw_data_metadata = tft.DatasetMetadata.from_feature_spec(feature_spec)
      >>> with tft_beam.Context(temp_dir=tempfile.mkdtemp()):
      ...   transformed_dataset, transform_fn = (
      ...       (raw_data, raw_data_metadata)
      ...       | tft_beam.AnalyzeAndTransformDataset(preprocessing_fn))
      >>> transformed_data, transformed_metadata = transformed_dataset
      >>> transformed_data
      [{'scaled': 0.0}, {'scaled': 0.5}, {'scaled': 1.0}]
  
      Returns:
        A `Tensor`, `SparseTensor`, or `RaggedTensor` containing the input column scaled to
        [output_min, output_max] on a per-key basis if a key is provided. If the
        analysis dataset is empty, a certain key contains a single distinct value or
        the computed key vocabulary doesn't have an entry for `key`, then `x` is
        scaled using a sigmoid function.
  
      Raises:
        ValueError: If output_min, output_max have the wrong order.
        NotImplementedError: If elementwise is True and key is not None.
        InvalidArgumentError: If indices of sparse x and key do not match.
      """
      # pyformat: enable
      with tf.compat.v1.name_scope(name, "scale_by_min_max_per_key"):
          if key is None:
              raise ValueError(
                  "key is None, call `tft.scale_by_min_max` instead"
              )
          return _scale_by_min_max_internal(
              x,
              key=key,
              output_min=output_min,
              output_max=output_max,
              elementwise=elementwise,
              key_vocabulary_filename=key_vocabulary_filename,
          )
  
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 6 for calling a global function with example usage: scale_by_min_max_per_key(x, key, output_min, output_max, elementwise, key_vocabulary_filename, name) and returns: _scale_by_min_max_internal