code: def is_categorical_column(
      data: pd.Series,
      valid_data: pd.Series,
      threshold: int = None,
      ratio: Optional[float] = None,
      oov_ratio_threshold: Optional[float] = None,
      is_label: bool = False,
  ) -> bool:
      """
      Identify whether a column is one categorical column.
      If the number of unique elements in the column is smaller than
  
          min(#Total Sample * ratio, threshold),
  
      it will be treated as a categorical column.
  
      Parameters
      ----------
      data
          One column of a multimodal pd.DataFrame for training.
      valid_data
          One column of a multimodal pd.DataFrame for validation.
      threshold
          The threshold for detecting categorical column.
      ratio
          The ratio detecting categorical column.
      oov_ratio_threshold
          The out-of-vocabulary ratio between training and validation.
          This is used to determine if the column is a categorical column.
          Usually, a categorical column can tolerate a small OOV ratio.
      is_label
          Whether the column is a label column.
  
      Returns
      -------
      Whether the column is a categorical column.
      """
      if data.dtype.name == "category":
          return True
      else:
          if threshold is None:
              if is_label:
                  # TODO(?) The following logic will be problematic if the task is few-shot learning.
                  threshold = 100
                  oov_ratio_threshold = 0
                  ratio = 0.1
              else:
                  threshold = 20
                  oov_ratio_threshold = 0
                  ratio = 0.1
          threshold = min(int(len(data) * ratio), threshold)
          try:
              data_value_counts = data.value_counts(dropna=False)
              key_set = set(data_value_counts.keys())
              if len(data_value_counts) < threshold:
                  valid_value_counts = valid_data.value_counts(
                      dropna=False
                  )
                  total_valid_num = len(valid_data)
                  oov_num = 0
                  for k, v in zip(
                      valid_value_counts.keys(),
                      valid_value_counts.values,
                  ):
                      if k not in key_set:
                          oov_num += v
                  if is_label and oov_num != 0:
                      return False
                  if oov_num / total_valid_num > oov_ratio_threshold:
                      return False
                  return True
              else:
                  return False
          except:
              return False
  
imports: import collections
  import json
  import logging
  import warnings
  from io import BytesIO
  from typing import Dict, List, Optional, Tuple, Union
  import pandas
  import PIL
  import pytesseract
  from autogluon.core.utils import infer_problem_type
  from ..constants import BINARY, CATEGORICAL, CLASSIFICATION, DOCUMENT_IMAGE, DOCUMENT_PDF, IDENTIFIER, IMAGE, IMAGE_BYTEARRAY, IMAGE_PATH, MULTICLASS, NER, NER_ANNOTATION, NULL, NUMERICAL, OBJECT_DETECTION, OPEN_VOCABULARY_OBJECT_DETECTION, REGRESSION, ROIS, SEMANTIC_SEGMENTATION, SEMANTIC_SEGMENTATION_GT, SEMANTIC_SEGMENTATION_IMG, TEXT, TEXT_NER
  from .utils import is_rois_input
label_desc: Use image node_id 1 for calling a global function with example usage: is_categorical_column(data, valid_data, threshold, ratio, oov_ratio_threshold, is_label) and returns: True, True, False, False, False, False