code: def scale_to_0_1_per_key(
      x: common_types.ConsistentTensorType,
      key: common_types.TensorType,
      elementwise: bool = False,
      key_vocabulary_filename: Optional[str] = None,
      name: Optional[str] = None,
  ) -> common_types.ConsistentTensorType:
      # pyformat: disable
      """Returns a column which is the input column scaled to have range [0,1].
  
      Args:
        x: A numeric `Tensor`, `SparseTensor`, or `RaggedTensor`.
        key: A `Tensor`, `SparseTensor`, or `RaggedTensor` of type string.
        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_to_0_1_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 [0, 1],
        per key. If the analysis dataset is empty, 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.
      """
      # pyformat: enable
      with tf.compat.v1.name_scope(name, "scale_to_0_1_per_key"):
          if key is None:
              raise ValueError(
                  "key is None, call `tft.scale_to_0_1` instead"
              )
          return _scale_by_min_max_internal(
              x,
              key=key,
              output_min=0,
              output_max=1,
              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 9 for calling a global function with example usage: scale_to_0_1_per_key(x, key, elementwise, key_vocabulary_filename, name) and returns: _scale_by_min_max_internal