code: def sample_rows(
      data, partitions, size, disjoint=True, *, rng_spec=None
  ):
      """
      Sample train-test a frame of ratings into train-test partitions.  This function does not care
      what kind of data is in `data`, so long as it is a Pandas DataFrame (or equivalent).
  
      We can loop over a sequence of train-test pairs::
  
          >>> from lenskit import datasets
          >>> ratings = datasets.MovieLens('data/ml-latest-small').ratings
          >>> for train, test in sample_rows(ratings, 5, 1000):
          ...     print(len(test))
          1000
          1000
          1000
          1000
          1000
  
      Sometimes for testing, it is useful to just get a single pair::
  
          >>> train, test = sample_rows(ratings, None, 1000)
          >>> len(test)
          1000
          >>> len(test) + len(train) - len(ratings)
          0
  
      Args:
          data(pandas.DataFrame):
              Data frame containing ratings or other data to partition.
          partitions(int or None):
              The number of partitions to produce.  If ``None``, produce a _single_ train-test
              pair instead of an iterator or list.
          size(int):
              The size of each sample.
          disjoint(bool):
              If ``True``, force samples to be disjoint.
          rng_spec:
              The random number generator or seed (see :py:func:`seedbank.numpy_rng`).
  
      Returns:
          iterator: An iterator of train-test pairs.
      """
  
      confirm_unique_index(data)
      rng = numpy_rng(rng_spec)
      if partitions is None:
          test = data.sample(n=size, random_state=rng)
          tr_mask = pd.Series(True, index=data.index)
          tr_mask.loc[test.index] = False
          train = data[tr_mask]
          return TTPair(train, test)
  
      if disjoint and partitions * size >= len(data):
          _logger.warning(
              "wanted %d disjoint splits of %d each, but only have %d rows; partitioning",
              partitions,
              size,
              len(data),
          )
          return partition_rows(data, partitions, rng_spec=rng)
  
      # create an array of indexes
      rows = np.arange(len(data))
  
      if disjoint:
          _logger.info(
              "creating %d disjoint samples of size %d",
              partitions,
              size,
          )
          ips = _disjoint_sample(rows, partitions, size, rng)
  
      else:
          _logger.info("taking %d samples of size %d", partitions, size)
          ips = _n_samples(rows, partitions, size, rng)
  
      return (
          TTPair(data.iloc[ip.train, :], data.iloc[ip.test, :])
          for ip in ips
      )
  
imports: from collections import namedtuple
  import logging
  from abc import ABC, abstractmethod
  import numpy
  import pandas
  from seedbank import numpy_rng
label_desc: Use image node_id 2 for calling a global function with example usage: sample_rows(data, partitions, size, disjoint) and returns: unknown, TTPair, partition_rows