code: def sample_data(cfg: Any, df: pd.DataFrame) -> pd.DataFrame:
      """Sample data from the dataframe"""
  
      if cfg.dataset.parent_id_column != "None" and "id" in df.columns:
          parent_mapping = df.set_index("id")["parent_id"].to_dict()
  
          # A recursive function to get the root id for each node
          def get_root(node):
              parent = parent_mapping.get(node)
              if parent is None or pd.isna(parent):
                  return node
              return get_root(parent)
  
          # Apply the function to assign each row the root id
          df["root_id"] = df["id"].apply(get_root)
  
          # Sample root_ids without replacement
          root_ids = df["root_id"].unique()
          n_sampled_root_ids = int(
              len(root_ids) * cfg.dataset.data_sample
          )
  
          np.random.seed(7331)
          sampled_root_ids = np.random.choice(
              root_ids, size=n_sampled_root_ids, replace=False
          )
  
          # Filter the dataframe to only include rows with sampled root_ids
          df = df[df["root_id"].isin(sampled_root_ids)].reset_index(
              drop=True
          )
          del df["root_id"]
      else:
          # at least 10 observations
          n = max(10, int(len(df) * cfg.dataset.data_sample))
          df = df.sample(
              n=min(n, len(df)), random_state=7331, replace=False
          )
  
      return df
  
imports: import logging
  import math
  import os
  from typing import Any, DefaultDict, Dict, List, Optional, Tuple, Union, no_type_check
  import networkx
  import numpy
  import pandas
  import pyarrow.parquet
  import torch
  from sklearn.model_selection import GroupShuffleSplit, train_test_split
  from torch import distributed
  from torch.utils.data import DataLoader, Sampler, SequentialSampler
  from llm_studio.src.datasets.conversation_chain_handler import ConversationChainHandler
  from llm_studio.src.utils.exceptions import LLMDataException
  from llm_studio.src.utils.utils import PatchedAttribute, set_seed
label_desc: Use image node_id 5 for calling a global function with example usage: sample_data(cfg, df) and returns: df, get_root, node