code: def data_transform(
      X_train,
      Y_train,
      X_test="",
      Y_test="",
      modeltype="Classification",
      multi_label=False,
      enc_method="label",
      scaler="",
  ):
      #### All these are needed for transforming cat variables and building a pipeline ###
      imp_constant = SimpleImputer(
          strategy="constant", fill_value="missing"
      )
      ohe = OneHotEncoder()
      imp_ohe = make_pipeline(imp_constant, ohe)
      vect = CountVectorizer()
      imp = SimpleImputer()
      le = My_LabelEncoder()
  
      def drop_second_col(Xt):
          ### This deletes the 2nd column. Hence col number=1 and axis=1 ###
          return np.delete(Xt, 1, 1)
  
      ####  This is where we define the Pipeline for cat encoders and Label Encoder ############
      lep = My_LabelEncoder_Pipe()
      drop_second_col_func = FunctionTransformer(drop_second_col)
      ### lep_one uses My_LabelEncoder to first label encode and then drop the second unused column ##
      lep_one = make_pipeline(lep, drop_second_col_func)
  
      ### if you drop remainder variables, then leftovervars is not needed.
      ### If you passthrough remainder variables, then leftovers must be included
      remainder = "drop"
  
      ### If you choose MaxAbsScaler, then NaNs which were Label Encoded as -1 are preserved as - (negatives). This is fantastic.
      ### If you choose StandardScaler or MinMaxScaler, the integer values become stretched as if they are far
      ###    apart when in reality they are close. So avoid it for now.
      scaler = MaxAbsScaler()
      # scaler = StandardScaler()
      ##### First make sure that the originals are not modified ##########
      X_train_encoded = copy.deepcopy(X_train)
      X_test_encoded = copy.deepcopy(X_test)
      ##### Use My_Label_Encoder to transform label targets if needed #####
      if multi_label:
          if modeltype != "Regression":
              targets = Y_train.columns
              Y_train_encoded = copy.deepcopy(Y_train)
              for each_target in targets:
                  mlb = My_LabelEncoder()
                  if not isinstance(Y_train, str):
                      Y_train_encoded[each_target] = mlb.fit_transform(
                          Y_train[each_target]
                      )
                  else:
                      Y_train_encoded = copy.deepcopy(Y_train)
                  if not isinstance(Y_test, str):
                      Y_test_encoded = mlb.transform(Y_test)
                  else:
                      Y_test_encoded = copy.deepcopy(Y_test)
          else:
              Y_train_encoded = copy.deepcopy(Y_train)
              Y_test_encoded = copy.deepcopy(Y_test)
      else:
          if modeltype != "Regression":
              mlb = My_LabelEncoder()
              if not isinstance(Y_train, str):
                  Y_train_encoded = mlb.fit_transform(Y_train)
              else:
                  Y_train_encoded = copy.deepcopy(Y_train)
              if not isinstance(Y_test, str):
                  Y_test_encoded = mlb.transform(Y_test)
              else:
                  Y_test_encoded = copy.deepcopy(Y_test)
          else:
              Y_train_encoded = copy.deepcopy(Y_train)
              Y_test_encoded = copy.deepcopy(Y_test)
  
      #### This is where we find out how to transform X_train and X_test  ####
      catvars = (
          X_train.select_dtypes("object").columns.tolist()
          + X_train.select_dtypes("category").columns.tolist()
      )
      numvars = X_train.select_dtypes("number").columns.tolist()
      ########    This is where we define the pipeline for cat variables ###########
      ### How do we make sure that we create one new LE_Pipe for each catvar? This is one way.
      init_str = "make_column_transformer("
      middle_str = "".join(
          [
              "(lep_one, catvars[" + str(i) + "]),"
              for i in range(len(catvars))
          ]
      )
      end_str = "(imp, numvars),    remainder=remainder)"
      full_str = init_str + middle_str + end_str
      ct = eval(full_str)
      pipe = make_pipeline(ct, scaler)
      ###  You will get a multidimensional numpy array ############
      dfo = pipe.fit_transform(X_train)
      if not isinstance(X_test, str):
          dfn = pipe.fit_transform(X_test)
  
      ### The first columns should be whatever is in the Transformer_Pipeline list of columns
      ### Hence they will be catvars. The second list will be numvars. Then only other columns that are passed through.
      ### So after the above 2 lists, you will get remainder cols unchanged: we call them leftovers.
      leftovervars = left_subtract(
          X_train.columns.tolist(), catvars + numvars
      )
  
      ## So if you do it correctly, you will get the list of names in proper order this way:
      ## first is catvars, then numvars and then leftovervars
      if remainder == "drop":
          cols_names = catvars + numvars
      else:
          cols_names = catvars + numvars + leftovervars
  
      dfo = pd.DataFrame(dfo, columns=cols_names)
      if not isinstance(X_test, str):
          dfn = pd.DataFrame(dfn, columns=cols_names)
  
      copy_names = copy.deepcopy(cols_names)
  
      for each_col in copy_names:
          X_train_encoded[each_col] = dfo[each_col].values
          if not isinstance(X_test, str):
              X_test_encoded[each_col] = dfn[each_col].values
  
      return (
          X_train_encoded,
          Y_train_encoded,
          X_test_encoded,
          Y_test_encoded,
          pipe,
      )
  
imports: import pandas
  import numpy
  from sklearn.model_selection import train_test_split
  from sklearn.model_selection import KFold
  from sklearn.model_selection import GridSearchCV
  from sklearn.multioutput import MultiOutputClassifier, MultiOutputRegressor
  from sklearn.multiclass import OneVsRestClassifier
  import xgboost
  from xgboost.sklearn import XGBClassifier
  from xgboost.sklearn import XGBRegressor
  from sklearn.model_selection import train_test_split
  from sklearn.multiclass import OneVsRestClassifier
  from sklearn.preprocessing import LabelEncoder
  import lightgbm
  from sklearn.model_selection import KFold, cross_val_score, StratifiedKFold
  import seaborn
  from sklearn.preprocessing import OneHotEncoder, LabelEncoder, label_binarize
  import csv
  import re
  from xgboost import XGBRegressor, XGBClassifier
  from sklearn.metrics import mean_squared_log_error, mean_squared_error, balanced_accuracy_score
  from scipy import stats
  from sklearn.model_selection import RandomizedSearchCV
  import scipy
  import time
  import copy
  from sklearn.preprocessing import StandardScaler, MinMaxScaler
  from collections import Counter, defaultdict
  import pdb
  import time
  from sklearn.preprocessing import StandardScaler, MinMaxScaler
  from sklearn.impute import SimpleImputer
  from sklearn.preprocessing import OneHotEncoder
  from sklearn.feature_extraction.text import CountVectorizer
  from sklearn.linear_model import LogisticRegression
  from sklearn.compose import make_column_transformer
  from sklearn.pipeline import make_pipeline
  from sklearn.preprocessing import LabelEncoder, LabelBinarizer
  from sklearn.base import BaseEstimator, TransformerMixin
  import pdb
  from sklearn.base import TransformerMixin
  from collections import defaultdict
  from sklearn.preprocessing import MaxAbsScaler
  from sklearn.preprocessing import FunctionTransformer
  from ..utils import My_LabelEncoder, My_LabelEncoder_Pipe
  from ..utils import left_subtract
  import xgboost
  from sklearn.utils.class_weight import compute_class_weight
  import copy
  from collections import Counter
  from collections import OrderedDict
  from collections import defaultdict
  from collections import OrderedDict
  from sklearn.impute import SimpleImputer
label_desc: Use image node_id 6 for calling a global function with example usage: data_transform(X_train, Y_train, X_test, Y_test, modeltype, multi_label, enc_method, scaler) and returns: X_train_encoded,  Y_train_encoded,  X_test_encoded,  Y_test_encoded,  pipe, np