code: def apply(self, df, train=True):
      df = (
          df.copy()
      )  # dep_fix: SettingWithCopy - prevent original DataFrame from losing old label columns
  
      labels_exist = True
      lst = self.label_columns[:]
      if not all(x in df.columns.values for x in lst):
          labels_exist = False
      if train and not labels_exist:
          raise ValueError(
              "dataframe is missing label columns: %s"
              % (self.label_columns)
          )
  
      # extract targets
      # todo: sort?
      if len(self.label_columns) > 1:
          if train and self.is_regression:
              warnings.warn(
                  "is_regression=True was supplied but ignored because multiple label columns imply classification"
              )
          cols = df.columns.values
          missing_cols = []
          for l in self.label_columns:
              if l not in df.columns.values:
                  missing_cols.append(l)
          if len(missing_cols) > 0:
              raise ValueError(
                  "These label_columns do not exist in df: %s"
                  % (missing_cols)
              )
  
          # set targets
          targets = (
              df[self.label_columns].values
              if labels_exist
              else np.zeros((df.shape[0], len(self.label_columns)))
          )
          # set class names
          if train:
              self.set_classes(self.label_columns)
      # single column
      else:
          # set targets
          targets = (
              df[self.label_columns[0]].values
              if labels_exist
              else np.zeros(df.shape[0], dtype=np.int_)
          )
          if self.is_regression and isinstance(targets[0], str):
              warnings.warn(
                  "is_regression=True was supplied but targets are strings - casting to floats"
              )
              targets = targets.astype(np.float64)
  
          # set class_names if classification task and targets with integer labels
          if (
              train
              and not self.is_regression
              and not isinstance(targets[0], str)
          ):
              class_names = list(set(targets))
              class_names.sort()
              class_names = list(map(str, class_names))
              if len(class_names) == 2:
                  class_names = [
                      "not_" + self.label_columns[0],
                      self.label_columns[0],
                  ]
              else:
                  class_names = [
                      self.label_columns[0] + "_" + c
                      for c in class_names
                  ]
              self.set_classes(class_names)
  
      # transform targets
      targets = super().apply(
          targets, train=train
      )  # self.c (new label_columns) may be modified here
      targets = (
          targets
          if len(targets.shape) > 1
          else np.expand_dims(targets, 1)
      )  # since self.label_columns is list
  
      # modify DataFrame
      if labels_exist:
          for l in self.label_columns:
              del df[l]  # delete old label columns
  
      new_lab_cols = self.get_label_columns(squeeze=False)
      if len(new_lab_cols) != targets.shape[1]:
          raise ValueError(
              "mismatch between target shape and number of labels - please open ktrain GitHub issue"
          )
      for i, col in enumerate(new_lab_cols):
          df[col] = targets[:, i]
      df[new_lab_cols] = targets
      print(new_lab_cols)
      print(df[new_lab_cols].head())
      df[new_lab_cols] = df[new_lab_cols].astype("float32")
  
      return df
  
imports: from .imports import *
  from subprocess import Popen
label_desc: Use image node_id 3 for calling the YTransformDataFrame obj's underlying member method code with example usage: obj.apply(df, train) and returns: df