class_docstr: Splitters split up Datasets into pieces for training/validation/testing.
  
  In machine learning applications, it's often necessary to split up a dataset
  into training/validation/test sets. Or to k-fold split a dataset (that is,
  divide into k equal subsets) for cross-validation. The `Splitter` class is
  an abstract superclass for all splitters that captures the common API across
  splitter classes.
  
  Note that `Splitter` is an abstract superclass. You won't want to
  instantiate this class directly. Rather you will want to use a concrete
  subclass for your application.
class_docstr_tok: ["Splitters","split","up","Datasets","into","pieces","for","training\/validation\/testing",".","In","machine","learning","applications",",","it","'s","often","necessary","to","split","up","a","dataset","into","training\/validation\/test","sets",".","Or","to","k-fold","split","a","dataset","(","that","is",",","divide","into","k","equal","subsets",")","for","cross-validation",".","The","`","Splitter","`","class","is","an","abstract","superclass","for","all","splitters","that","captures","the","common","API","across","splitter","classes",".","Note","that","`","Splitter","`","is","an","abstract","superclass",".","You","wo","n't","want","to","instantiate","this","class","directly",".","Rather","you","will","want","to","use","a","concrete","subclass","for","your","application","."]
docstr: Parameters
  ----------
  dataset: Dataset
      Dataset to do a k-fold split
  k: int
      Number of folds to split `dataset` into.
  directories: List[str], optional (default None)
      List of length 2*k filepaths to save the result disk-datasets.
  
  Returns
  -------
  List[Tuple[Dataset, Dataset]]
      List of length k tuples of (train, cv) where `train` and `cv` are both `Dataset`.
docstr_tok: ["Parameters","--","--","--","--","--","dataset",":","Dataset","Dataset","to","do","a","k-fold","split","k",":","int","Number","of","folds","to","split","`","dataset","`","into",".","directories",":","List","[","str","]",",","optional","(","default","None",")","List","of","length","2","*","k","filepaths","to","save","the","result","disk-datasets",".","Returns","--","--","--","-","List","[","Tuple","[","Dataset",",","Dataset","]","]","List","of","length","k","tuples","of","(","train",",","cv",")","where","`","train","`","and","`","cv","`","are","both","`","Dataset","`","."]
code: def k_fold_split(
      self,
      dataset: Dataset,
      k: int,
      directories: Optional[List[str]] = None,
      **kwargs,
  ) -> List[Tuple[Dataset, Dataset]]:
      """
      Parameters
      ----------
      dataset: Dataset
          Dataset to do a k-fold split
      k: int
          Number of folds to split `dataset` into.
      directories: List[str], optional (default None)
          List of length 2*k filepaths to save the result disk-datasets.
  
      Returns
      -------
      List[Tuple[Dataset, Dataset]]
          List of length k tuples of (train, cv) where `train` and `cv` are both `Dataset`.
      """
      logger.info("Computing K-fold split")
      if directories is None:
          directories = [tempfile.mkdtemp() for _ in range(2 * k)]
      else:
          assert len(directories) == 2 * k
      cv_datasets = []
      train_ds_base = None
      train_datasets = []
      # rem_dataset is remaining portion of dataset
      if isinstance(dataset, DiskDataset):
          rem_dataset = dataset
      else:
          rem_dataset = DiskDataset.from_numpy(
              dataset.X, dataset.y, dataset.w, dataset.ids
          )
  
      for fold in range(k):
          # Note starts as 1/k since fold starts at 0. Ends at 1 since fold goes up
          # to k-1.
          frac_fold = 1.0 / (k - fold)
          train_dir, cv_dir = (
              directories[2 * fold],
              directories[2 * fold + 1],
          )
          fold_inds, rem_inds, _ = self.split(
              rem_dataset,
              frac_train=frac_fold,
              frac_valid=1 - frac_fold,
              frac_test=0,
              **kwargs,
          )
          cv_dataset = rem_dataset.select(fold_inds, select_dir=cv_dir)
          cv_datasets.append(cv_dataset)
          # FIXME: Incompatible types in assignment (expression has type "Dataset", variable has type "DiskDataset")
          rem_dataset = rem_dataset.select(rem_inds)  # type: ignore
  
          train_ds_to_merge: Iterator[Dataset] = filter(
              None, [train_ds_base, rem_dataset]
          )
          train_ds_to_merge = filter(
              lambda x: len(x) > 0, train_ds_to_merge
          )
          train_dataset = DiskDataset.merge(
              train_ds_to_merge, merge_dir=train_dir
          )
          train_datasets.append(train_dataset)
  
          update_train_base_merge: Iterator[Dataset] = filter(
              None, [train_ds_base, cv_dataset]
          )
          train_ds_base = DiskDataset.merge(update_train_base_merge)
      return list(zip(train_datasets, cv_datasets))
  
imports: import inspect
  import itertools
  import logging
  import os
  import random
  import tempfile
  from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple, Union
  import deepchem
  import numpy
  import pandas
  from deepchem.data import Dataset, DiskDataset
  from deepchem.utils import get_print_threshold
label_desc: Use image node_id 1 for calling the Splitter obj's underlying member method code with example usage: obj.k_fold_split(dataset, k, directories) and returns: list