docstr: :param object/list data: Data for augmentation. It can be list of data (e.g. list 
      of string or numpy) or single element (e.g. string or numpy). Numpy format only
      supports audio or spectrogram data. For text data, only support string or
      list of string.
  :param int n: Default is 1. Number of unique augmented output. Will be force to 1 
      if input is list of data
  :param int num_thread: Number of thread for data augmentation. Use this option 
      when you are using CPU and n is larger than 1
  :return: Augmented data
  
  >>> augmented_data = aug.augment(data)
docstr_tok: [":","param","object\/list","data",":","Data","for","augmentation",".","It","can","be","list","of","data","(","e.g",".","list","of","string","or","numpy",")","or","single","element","(","e.g",".","string","or","numpy",")",".","Numpy","format","only","supports","audio","or","spectrogram","data",".","For","text","data",",","only","support","string","or","list","of","string",".",":","param","int","n",":","Default","is","1",".","Number","of","unique","augmented","output",".","Will","be","force","to","1","if","input","is","list","of","data",":","param","int","num_thread",":","Number","of","thread","for","data","augmentation",".","Use","this","option","when","you","are","using","CPU","and","n","is","larger","than","1",":","return",":","Augmented","data",">",">",">","augmented_data","=","aug.augment","(","data",")"]
code: def augment(self, data, n=1, num_thread=1):
      """
      :param object/list data: Data for augmentation. It can be list of data (e.g. list
          of string or numpy) or single element (e.g. string or numpy). Numpy format only
          supports audio or spectrogram data. For text data, only support string or
          list of string.
      :param int n: Default is 1. Number of unique augmented output. Will be force to 1
          if input is list of data
      :param int num_thread: Number of thread for data augmentation. Use this option
          when you are using CPU and n is larger than 1
      :return: Augmented data
  
      >>> augmented_data = aug.augment(data)
  
      """
      max_retry_times = 3  # max loop times of n to generate expected number of outputs
      aug_num = 1 if isinstance(data, list) else n
      expected_output_num = (
          len(data) if isinstance(data, list) else aug_num
      )
  
      exceptions = self._validate_augment(data)
      # TODO: Handle multiple exceptions
      for exception in exceptions:
          if isinstance(exception, WarningException):
              if self.verbose > 0:
                  exception.output()
  
              # Return empty value per data type
              if isinstance(data, str):
                  return []
              elif isinstance(data, list):
                  return []
              elif isinstance(data, np.ndarray):
                  return np.array([])
  
              return []
  
      action_fx = None
      clean_data = self.clean(data)
      if self.action == Action.INSERT:
          action_fx = self.insert
      elif self.action == Action.SUBSTITUTE:
          action_fx = self.substitute
      elif self.action == Action.SWAP:
          action_fx = self.swap
      elif self.action == Action.DELETE:
          action_fx = self.delete
      elif self.action == Action.CROP:
          action_fx = self.crop
      elif self.action == Action.SPLIT:
          action_fx = self.split
  
      for _ in range(max_retry_times + 1):
          augmented_results = []
  
          # By design, it is one-to-many
          if self.__class__.__name__ in ["LambadaAug"]:
              augmented_results = action_fx(clean_data, n=n)
          # PyTorch's augmenter
          elif self.__class__.__name__ in [
              "AbstSummAug",
              "BackTranslationAug",
              "ContextualWordEmbsAug",
              "ContextualWordEmbsForSentenceAug",
          ]:
              for _ in range(aug_num):
                  result = action_fx(clean_data)
                  if isinstance(result, list):
                      augmented_results.extend(result)
                  else:
                      augmented_results.append(result)
          # Multi inputs
          elif isinstance(data, list):
              # Single Thread
              if num_thread == 1:
                  augmented_results = [action_fx(d) for d in clean_data]
  
              # Multi Thread
              else:
                  batch_data = [
                      data[i : i + num_thread]
                      for i in range(0, len(data), num_thread)
                  ]
                  for mini_batch_data in batch_data:
                      augmented_results.extend(
                          self._parallel_augments(
                              self.augment, mini_batch_data
                          )
                      )
  
          # Single input with/without multiple input
          else:
              # Single Thread
              if num_thread == 1:
                  augmented_results = [
                      action_fx(clean_data) for _ in range(n)
                  ]
  
              # Multi Thread
              else:
                  augmented_results = self._parallel_augment(
                      action_fx, clean_data, n=n, num_thread=num_thread
                  )
  
          if len(augmented_results) >= expected_output_num:
              break
  
      if len(augmented_results) == 0:
          # if not result, return itself
          if isinstance(data, list):
              return data
          # Single input with/without multiple input
          else:
              return [data]
  
      if isinstance(augmented_results, pd.DataFrame):
          return augmented_results
      else:
          if isinstance(data, list):
              return augmented_results
          else:
              return augmented_results[:n]
  
imports: import math
  import random
  import numpy
  import pandas
  from multiprocessing.dummy import Pool
  from nlpaug.util import Action, Method, WarningException, WarningName, WarningCode, WarningMessage
label_desc: Use image node_id 3 for calling the Augmenter obj's underlying member method code with example usage: obj.augment(data, n, num_thread) and returns: augmented_results, list, data, list, augmented_results, augmented_results, list, list, np