docstr: Encode columns with provided list of StringIndex. Unknown string will be
  None after the encoding and you may need to fillna with 0.
  
  :param columns: str or a list of str, the target columns to be encoded.
  :param indices: StringIndex or a list of StringIndex, StringIndexes of target columns.
         The StringIndex should at least have two columns: id and the corresponding
         categorical column.
         Or it can be a dict or a list of dicts. In this case,
         the keys of the dict should be within the categorical column
         and the values are the target ids to be encoded.
  :param broadcast: bool, whether need to broadcast index when encode string.
         Default is True.
  :param do_split: bool, whether need to split column value to array to encode string.
         Default is False.
  :param sep: str, a string representing a regular expression to split a column value.
         Default is ','.
  :param sort_for_array: bool, whether need to sort array columns. Default is False.
  :param keep_most_frequent: bool, whether need to keep most frequent value as the
         column value. Default is False.
  
  :return: A new FeatureTable which transforms categorical features into unique integer
           values with provided StringIndexes.
docstr_tok: ["Encode","columns","with","provided","list","of","StringIndex",".","Unknown","string","will","be","None","after","the","encoding","and","you","may","need","to","fillna","with","0.",":","param","columns",":","str","or","a","list","of","str",",","the","target","columns","to","be","encoded",".",":","param","indices",":","StringIndex","or","a","list","of","StringIndex",",","StringIndexes","of","target","columns",".","The","StringIndex","should","at","least","have","two","columns",":","id","and","the","corresponding","categorical","column",".","Or","it","can","be","a","dict","or","a","list","of","dicts",".","In","this","case",",","the","keys","of","the","dict","should","be","within","the","categorical","column","and","the","values","are","the","target","ids","to","be","encoded",".",":","param","broadcast",":","bool",",","whether","need","to","broadcast","index","when","encode","string",".","Default","is","True",".",":","param","do_split",":","bool",",","whether","need","to","split","column","value","to","array","to","encode","string",".","Default","is","False",".",":","param","sep",":","str",",","a","string","representing","a","regular","expression","to","split","a","column","value",".","Default","is","'",",","'",".",":","param","sort_for_array",":","bool",",","whether","need","to","sort","array","columns",".","Default","is","False",".",":","param","keep_most_frequent",":","bool",",","whether","need","to","keep","most","frequent","value","as","the","column","value",".","Default","is","False",".",":","return",":","A","new","FeatureTable","which","transforms","categorical","features","into","unique","integer","values","with","provided","StringIndexes","."]
code: def encode_string(
      self,
      df: "SparkDataFrame",
      columns: Union[str, List[str]],
      indices: Union["StringIndex", List["StringIndex"]],
      broadcast: bool = True,
      do_split: bool = False,
      sep: str = ",",
      sort_for_array: bool = False,
      keep_most_frequent: bool = False,
  ) -> "SparkDataFrame":
      """
      Encode columns with provided list of StringIndex. Unknown string will be
      None after the encoding and you may need to fillna with 0.
  
      :param columns: str or a list of str, the target columns to be encoded.
      :param indices: StringIndex or a list of StringIndex, StringIndexes of target columns.
             The StringIndex should at least have two columns: id and the corresponding
             categorical column.
             Or it can be a dict or a list of dicts. In this case,
             the keys of the dict should be within the categorical column
             and the values are the target ids to be encoded.
      :param broadcast: bool, whether need to broadcast index when encode string.
             Default is True.
      :param do_split: bool, whether need to split column value to array to encode string.
             Default is False.
      :param sep: str, a string representing a regular expression to split a column value.
             Default is ','.
      :param sort_for_array: bool, whether need to sort array columns. Default is False.
      :param keep_most_frequent: bool, whether need to keep most frequent value as the
             column value. Default is False.
  
      :return: A new FeatureTable which transforms categorical features into unique integer
               values with provided StringIndexes.
      """
      if not isinstance(columns, list):
          columns = [columns]
      if not isinstance(indices, list):
          indices = [indices]
      invalidInputError(
          len(columns) == len(indices),
          "columns len doesn't match indices lenngth",
      )
      if isinstance(indices[0], dict):
          indices = list(
              map(
                  lambda x: StringIndex.from_dict(
                      x[1], columns[x[0]]
                  ),  # type:ignore
                  enumerate(indices),
              )
          )
      data_df = df
      for i in range(len(columns)):
          index_tbl = indices[i]
          col_name = columns[i]
          if broadcast:
              index_tbl.broadcast()
          if not do_split:
              data_df = (
                  data_df.join(index_tbl.df, col_name, how="left")
                  .drop(col_name)
                  .withColumnRenamed("id", col_name)
              )
          else:
              data_df = data_df.withColumn(
                  "row_id", F.monotonically_increasing_id()
              )
              tmp_df = data_df.select("row_id", col_name).withColumn(
                  col_name, F.explode(F.split(F.col(col_name), sep))
              )
              tmp_df = tmp_df.join(
                  index_tbl.df, col_name, how="left"
              ).filter(F.col("id").isNotNull())
              tmp_df = tmp_df.select("row_id", F.col("id"))
              if keep_most_frequent:
                  tmp_df = tmp_df.groupby("row_id").agg(
                      F.array_sort(F.collect_list(F.col("id")))
                      .getItem(0)
                      .alias("id")
                  )
              elif sort_for_array:
                  tmp_df = tmp_df.groupby("row_id").agg(
                      F.array_sort(F.collect_list(F.col("id"))).alias(
                          "id"
                      )
                  )
              else:
                  tmp_df = tmp_df.groupby("row_id").agg(
                      F.collect_list(F.col("id")).alias("id")
                  )
              data_df = (
                  data_df.join(tmp_df, "row_id", "left")
                  .drop("row_id")
                  .drop(col_name)
                  .withColumnRenamed("id", col_name)
              )
  
      return data_df
  
imports: import pyspark.sql.functions
  from pyspark.sql import Row
  from pyspark.sql.types import IntegerType, StructType, StringType, StructField
  from bigdl.dllib.utils.log4Error import invalidInputError
  from bigdl.orca.data import SparkXShards
  from bigdl.orca import OrcaContext
  from pyspark.ml.feature import MinMaxScaler
  from pyspark.ml.feature import StandardScaler
  from pyspark.ml.feature import VectorAssembler
  from pyspark.ml import Pipeline
  from bigdl.orca.data.utils import *
  import uuid
  from typing import TYPE_CHECKING, Tuple, Union, List
label_desc: Use image node_id 7 for calling the StringIndexer obj's underlying member method code with example usage: obj.encode_string(df, columns, indices, broadcast, do_split, sep, sort_for_array, keep_most_frequent) and returns: data_df