code: def sample(
      df: "DataFrame", n=None, frac: float = None, random_state=None
  ) -> "DataFrame":
      """
      only support down sample, n should <= df.shape, or fact = 1
      """
  
      if n is not None and frac is not None:
          raise ValueError(
              "sample's parameters n and frac should not be set in the same time."
          )
  
      if frac is not None:
          if frac > 1:
              raise ValueError(
                  f"sample's parameter frac={frac} should <= 1.0"
              )
          n = max(1, int(df.shape[0] * frac))
  
      if n > df.shape[0]:
          raise ValueError(
              f"sample's parameter n={n} > data size={df.shape[0]}"
          )
  
      if n == 0:
          raise ValueError(f"sample's parameter n={n} should >= 1")
  
      indexer = list(df.get_indexer(target="sample_id").collect())
      sample_indexer = resample(
          indexer, replace=False, n_samples=n, random_state=random_state
      )
  
      sample_indexer = df._ctx.computing.parallelize(
          sample_indexer,
          include_key=True,
          partition=df.block_table.num_partitions,
      )
  
      sample_frame = df.loc(sample_indexer)
  
      return sample_frame
  
imports: import copy
  import functools
  from typing import List, Union
  import torch
  from sklearn.utils import resample
  from .._dataframe import DataFrame
  from ..manager.data_manager import DataManager
  from ..manager.block_manager import Block
  from ._compress_block import compress_blocks
  from ._indexer import get_partition_order_by_raw_table, get_partition_order_mappings_by_block_table
  from ._promote_types import promote_partial_block_types
  from ._set_item import set_item
  from fate.arch.tensor import DTensor
label_desc: Use image node_id 4 for calling a global function with example usage: sample(df, n, frac, random_state) and returns: sample_frame