class_docstr: Encapsulate features, labels, and metadata for a given dataset.
  
  Parameters
  ----------
  name : str
      The name of this feature set.
  
  ids : Union[List[str], numpy.ndarray]
      Example IDs for this set.
  
  labels : Optional[Union[List[str], numpy.ndarray], default=None
      Labels for this set.
  
  features : Optional[Union[:class:`skll.types.FeatureDictList`, :class:`numpy.ndarray`]], default=None
      The features for each instance represented as either a
      list of dictionaries or a numpy array (if ``vectorizer`` is
      also specified).
  
  vectorizer : Optional[Union[:class:`sklearn.feature_extraction.DictVectorizer`, :class:`sklearn.feature_extraction.FeatureHasher`], default=None
      Vectorizer which will be used to generate the feature matrix.
  
  Warnings
  --------
  FeatureSets can only be equal if the order of the instances is
  identical because these are stored as lists/arrays. Since scikit-learn's
  ``DictVectorizer`` automatically sorts the underlying feature matrix
  if it is sparse, we do not do any sorting before checking for equality.
  This is not a problem because we _always_ use sparse matrices with
  ``DictVectorizer`` when creating FeatureSets.
  
  Notes
  -----
  If ids, labels, and/or features are not None, the number of rows in
  each array must be equal.
docstr: Split ``FeatureSet`` into two new ``FeatureSet`` instances.
  
  The splitting is done based on the given indices for the two splits.
  
  Parameters
  ----------
  fs : skll.data.featureset.FeatureSet
      The ``FeatureSet`` instance to split.
  
  ids_for_split1 : List[int]
      A list of example indices which will be split out into
      the first ``FeatureSet`` instance. Note that the
      FeatureSet instance will respect the order of the
      specified indices.
  
  ids_for_split2 : Optional[List[int]], default=None
      An optional list of example indices which will be
      split out into the second ``FeatureSet`` instance.
      Note that the ``FeatureSet`` instance will respect
      the order of the specified indices. If this is
      not specified, then the second ``FeatureSet``
      instance will contain the complement of the
      first set of indices sorted in ascending order.
  
  Returns
  -------
  Tuple[:class:`skll.data.featureset.FeatureSet`, :class:`skll.data.featureset.FeatureSet`]
      A tuple containing the two featureset instances.
docstr_tok: ["Split","``","FeatureSet","``","into","two","new","``","FeatureSet","``","instances",".","The","splitting","is","done","based","on","the","given","indices","for","the","two","splits",".","Parameters","--","--","--","--","--","fs",":","skll.data.featureset.FeatureSet","The","``","FeatureSet","``","instance","to","split",".","ids_for_split1",":","List","[","int","]","A","list","of","example","indices","which","will","be","split","out","into","the","first","``","FeatureSet","``","instance",".","Note","that","the","FeatureSet","instance","will","respect","the","order","of","the","specified","indices",".","ids_for_split2",":","Optional","[","List","[","int","]","]",",","default=None","An","optional","list","of","example","indices","which","will","be","split","out","into","the","second","``","FeatureSet","``","instance",".","Note","that","the","``","FeatureSet","``","instance","will","respect","the","order","of","the","specified","indices",".","If","this","is","not","specified",",","then","the","second","``","FeatureSet","``","instance","will","contain","the","complement","of","the","first","set","of","indices","sorted","in","ascending","order",".","Returns","--","--","--","-","Tuple","[",":","class",":","`","skll.data.featureset.FeatureSet","`",",",":","class",":","`","skll.data.featureset.FeatureSet","`","]","A","tuple","containing","the","two","featureset","instances","."]
code: def split(
      fs: "FeatureSet",
      ids_for_split1: List[int],
      ids_for_split2: Optional[List[int]] = None,
  ) -> Tuple["FeatureSet", "FeatureSet"]:
      """
      Split ``FeatureSet`` into two new ``FeatureSet`` instances.
  
      The splitting is done based on the given indices for the two splits.
  
      Parameters
      ----------
      fs : skll.data.featureset.FeatureSet
          The ``FeatureSet`` instance to split.
  
      ids_for_split1 : List[int]
          A list of example indices which will be split out into
          the first ``FeatureSet`` instance. Note that the
          FeatureSet instance will respect the order of the
          specified indices.
  
      ids_for_split2 : Optional[List[int]], default=None
          An optional list of example indices which will be
          split out into the second ``FeatureSet`` instance.
          Note that the ``FeatureSet`` instance will respect
          the order of the specified indices. If this is
          not specified, then the second ``FeatureSet``
          instance will contain the complement of the
          first set of indices sorted in ascending order.
  
      Returns
      -------
      Tuple[:class:`skll.data.featureset.FeatureSet`, :class:`skll.data.featureset.FeatureSet`]
          A tuple containing the two featureset instances.
      """
      # Note: an alternative way to implement this is to make copies
      # of the given FeatureSet instance and then use the `filter()`
      # method but that wastes too much memory since it requires making
      # two copies of the original FeatureSet which may be huge. With
      # the current implementation, we are creating new objects but
      # they should be much smaller than the original FeatureSet.
      ids1 = fs.ids[ids_for_split1]
      labels1 = (
          fs.labels[ids_for_split1] if fs.labels is not None else None
      )
      features1 = (
          fs.features[ids_for_split1]
          if fs.features is not None
          else None
      )
  
      # if ids_for_split2 is not given, it will be the complement of ids_split1
      if ids_for_split2 is None:
          ids_for_split2 = [
              ind
              for ind in range(len(fs.ids))
              if ind not in ids_for_split1
          ]
  
      ids2 = fs.ids[ids_for_split2]
      labels2 = (
          fs.labels[ids_for_split2] if fs.labels is not None else None
      )
      features2 = (
          fs.features[ids_for_split2]
          if fs.features is not None
          else None
      )
  
      fs1 = FeatureSet(
          f"{fs.name}_1",
          ids1,
          labels=labels1,
          features=features1,
          vectorizer=fs.vectorizer,
      )
      fs2 = FeatureSet(
          f"{fs.name}_2",
          ids2,
          labels=labels2,
          features=features2,
          vectorizer=fs.vectorizer,
      )
      return fs1, fs2
  
imports: from copy import deepcopy
  from typing import Collection, List, Optional, Tuple, Union
  import numpy
  import scipy.sparse
  from pandas import DataFrame
  from sklearn.feature_extraction import DictVectorizer, FeatureHasher
  from skll.data.dict_vectorizer import DictVectorizer
  from skll.types import FeatGenerator, FeatureDictList, IdType, LabelType, SparseFeatureMatrix
label_desc: Use image node_id 14 for calling the FeatureSet obj's underlying member method code with example usage: obj.split(fs, ids_for_split1, ids_for_split2) and returns: fs1,  fs2