docstr: Calculates preprocessing time per row for a given unprocessed data X and infer_limit_batch_size
  Returns an updated infer_limit if not None with preprocessing time per row subtracted
  Raises an exception if preprocessing time is greater than or equal to the infer_limit
docstr_tok: ["Calculates","preprocessing","time","per","row","for","a","given","unprocessed","data","X","and","infer_limit_batch_size","Returns","an","updated","infer_limit","if","not","None","with","preprocessing","time","per","row","subtracted","Raises","an","exception","if","preprocessing","time","is","greater","than","or","equal","to","the","infer_limit"]
code: def _update_infer_limit(
      self,
      X: DataFrame,
      *,
      infer_limit_batch_size: int,
      infer_limit: float = None,
  ):
      """
      Calculates preprocessing time per row for a given unprocessed data X and infer_limit_batch_size
      Returns an updated infer_limit if not None with preprocessing time per row subtracted
      Raises an exception if preprocessing time is greater than or equal to the infer_limit
      """
      X_batch = sample_df_for_time_func(
          df=X, sample_size=infer_limit_batch_size
      )
      infer_limit_batch_size_actual = len(X_batch)
      self.preprocess_1_time = (
          time_func(f=self.transform_features, args=[X_batch])
          / infer_limit_batch_size_actual
      )
      self.preprocess_1_batch_size = infer_limit_batch_size
      (
          preprocess_1_time_log,
          time_unit_preprocess_1_time,
      ) = convert_time_in_s_to_log_friendly(self.preprocess_1_time)
      logger.log(
          20,
          f"\t{round(preprocess_1_time_log, 3)}{time_unit_preprocess_1_time}\t= Feature Preprocessing Time (1 row | {infer_limit_batch_size} batch size)",
      )
  
      if infer_limit is not None:
          infer_limit_new = infer_limit - self.preprocess_1_time
          (
              infer_limit_log,
              time_unit_infer_limit,
          ) = convert_time_in_s_to_log_friendly(infer_limit)
          (
              infer_limit_new_log,
              time_unit_infer_limit_new,
          ) = convert_time_in_s_to_log_friendly(infer_limit_new)
  
          logger.log(
              20,
              f"\t\tFeature Preprocessing requires {round(self.preprocess_1_time/infer_limit*100, 2)}% "
              f"of the overall inference constraint ({infer_limit_log}{time_unit_infer_limit})\n"
              f"\t\t{round(infer_limit_new_log, 3)}{time_unit_infer_limit_new} inference time budget remaining for models...",
          )
          if infer_limit_new <= 0:
              infer_limit_new = 0
              logger.log(
                  30,
                  f"WARNING: Impossible to satisfy inference constraint, budget is exceeded during data preprocessing!\n"
                  f"\tAutoGluon will be unable to satisfy the constraint, but will return the fastest model it can.\n"
                  f"\tConsider using fewer features, relaxing the inference constraint, or simplifying the feature generator.",
              )
          infer_limit = infer_limit_new
      return infer_limit
  
imports: import copy
  import logging
  import math
  import time
  import numpy
  import pandas
  from pandas import DataFrame
  from autogluon.common.utils.log_utils import convert_time_in_s_to_log_friendly
  from autogluon.common.utils.system_info import get_ag_system_info
  from autogluon.core.constants import AUTO_WEIGHT, BALANCE_WEIGHT, BINARY, MULTICLASS, QUANTILE, REGRESSION
  from autogluon.core.data import LabelCleaner
  from autogluon.core.data.cleaner import Cleaner
  from autogluon.core.utils.time import sample_df_for_time_func, time_func
  from autogluon.core.utils.utils import augment_rare_classes, extract_column
  from ..trainer import AutoTrainer
  from .abstract_learner import AbstractTabularLearner
label_desc: Use image node_id 3 for calling the DefaultLearner obj's underlying member method code with example usage: obj._update_infer_limit(X) and returns: infer_limit