code: def split_train_test(
      ts: Union[pd.Series, pd.DataFrame],
      mode: int = 1,
      n_splits: int = 1,
      train_ratio: float = 0.7,
  ) -> List[
      Tuple[
          Union[pd.Series, pd.DataFrame], Union[pd.Series, pd.DataFrame]
      ]
  ]:
      """Split time series into training and testing set for cross validation.
  
      Parameters
      ----------
      ts: pandas Series or DataFrame
          Time series to process.
  
      mode: int, optional
          The split mode to use. Choose from 1, 2, 3 and 4.
  
          1. Divide time series into n_splits folds of equal length, split
             each fold into training and testing based on train_ratio.
  
          2. Create n_splits folds, where each fold starts at t_0 and ends
             at t_(n/n_splits), where n goes from 0 to n_splits and the
             first train_ratio of the fold is for training.
  
          3. Create n_splits folds, where each fold starts at t_0. Each fold
             has len(ts)/(1 + n_splits) test points at the end. Each fold is
             n * len(ts)/(1 + n_splits) long, where n ranges from 1 to
             n_splits.
  
          4. Create n_splits folds, where each fold starts at t_0. Each fold
             has n * len(ts)/(1 + n_splits) training points at the beginning
             of the time series, where n ranges from 1 to n_splits and the
             remaining points are testing points.
  
          Default: 1.
  
      n_splits: int, optional
          Number of splits. Default: 1.
  
      train_ratio: float, optional
          Ratio between length of training series and each fold, only used by
          mode 1 and 2. Default: 0.7.
  
      Returns
      -------
          list of 2-tuples (train, test)
              Splitted training and testing series.
  
      Examples
      --------
          In the following description of the four modes, 1s represent positions
          assigned to training, 2s represent those assigned to testing, 0s are
          those not assigned.
  
          For a time series with length 40, if `n_splits=4`, `train_ratio=0.7`,
  
          - If `mode=1`:
  
              1111111222000000000000000000000000000000
              0000000000111111122200000000000000000000
              0000000000000000000011111112220000000000
              0000000000000000000000000000001111111222
  
          - If `mode=2`:
  
              1111111222000000000000000000000000000000
              1111111111111122222200000000000000000000
              1111111111111111111112222222220000000000
              1111111111111111111111111111222222222222
  
          - If `mode=3`:
  
              1111111122222222000000000000000000000000
              1111111111111111222222220000000000000000
              1111111111111111111111112222222200000000
              1111111111111111111111111111111122222222
  
          - If `mode=4`:
  
              1111111122222222222222222222222222222222
              1111111111111111222222222222222222222222
              1111111111111111111111112222222222222222
              1111111111111111111111111111111122222222
  
      """
  
      if not isinstance(ts, (pd.DataFrame, pd.Series)):
          raise ValueError(
              "Argument `ts` must be a pandas Series or DataFrame."
          )
  
      splits = []
      if mode == 1:
          fold_len = round(len(ts) / n_splits)
          fold_pos = 0
          for _ in range(n_splits - 1):
              splits.append(
                  (
                      ts.iloc[
                          fold_pos : (
                              fold_pos + round(fold_len * train_ratio)
                          )
                      ],
                      ts.iloc[
                          (fold_pos + round(fold_len * train_ratio)) : (
                              fold_pos + fold_len
                          )
                      ],
                  )
              )
              fold_pos = fold_pos + fold_len
          splits.append(
              (
                  ts.iloc[
                      fold_pos : (
                          fold_pos
                          + round((len(ts) - fold_pos) * train_ratio)
                      )
                  ],
                  ts.iloc[
                      (
                          fold_pos
                          + round((len(ts) - fold_pos) * train_ratio)
                      ) :
                  ],
              )
          )
      elif mode == 2:
          for k_fold in range(n_splits - 1):
              fold_len = round(len(ts) / n_splits) * (k_fold + 1)
              splits.append(
                  (
                      ts.iloc[: round(fold_len * train_ratio)],
                      ts.iloc[round(fold_len * train_ratio) : fold_len],
                  )
              )
          splits.append(
              (
                  ts.iloc[: round(len(ts) * train_ratio)],
                  ts.iloc[round(len(ts) * train_ratio) : len(ts)],
              )
          )
      elif mode == 3:
          fold_len = round(len(ts) / (n_splits + 1))
          for k_fold in range(n_splits - 1):
              splits.append(
                  (
                      ts.iloc[: ((k_fold + 1) * fold_len)],
                      ts.iloc[
                          ((k_fold + 1) * fold_len) : (
                              (k_fold + 2) * fold_len
                          )
                      ],
                  )
              )
          splits.append(
              (
                  ts.iloc[: (n_splits * fold_len)],
                  ts.iloc[(n_splits * fold_len) :],
              )
          )
      elif mode == 4:
          fold_len = round(len(ts) / (n_splits + 1))
          for k_fold in range(n_splits):
              splits.append(
                  (
                      ts.iloc[: ((k_fold + 1) * fold_len)],
                      ts.iloc[((k_fold + 1) * fold_len) :],
                  )
              )
      else:
          raise ValueError(
              "Argument `mode` must be one of 1, 2, 3, and 4."
          )
  
      return splits
  
file_path: adtk/src/adtk/data/_data.py
imports: from typing import Dict, List, Optional, Tuple, Union, overload
  import numpy
  import pandas
label_desc: Use image node_id 14 for calling a global function with example usage: split_train_test(ts, mode, n_splits, train_ratio) and returns: splits