code: def create_stats(
      df,
      tenant_col: str,
      value_col: str = AccessAnomalyConfig.default_output_col,
  ) -> StatsMap:
      stat_rows = (
          df.groupBy(tenant_col)
          .agg(
              f.count("*").alias("__count__"),
              f.min(f.col(value_col)).alias("__min__"),
              f.max(f.col(value_col)).alias("__max__"),
              f.mean(f.col(value_col)).alias("__mean__"),
              f.stddev_pop(f.col(value_col)).alias("__std__"),
          )
          .collect()
      )
  
      stats_map = {
          row[tenant_col]: BasicStats(
              row["__count__"],
              row["__min__"],
              row["__max__"],
              row["__mean__"],
              row["__std__"],
          )
          for row in stat_rows
      }
  
      return StatsMap(stats_map)
  
imports: import os
  import tempfile
  import unittest
  from typing import Dict, Optional, Set, Type, Union
  from pandas.testing import assert_frame_equal
  from pyspark.sql import DataFrame, types, functions
  from synapse.ml.cyber.feature import indexers
  from synapse.ml.cyber import DataFactory
  from synapse.ml.cyber.anomaly.collaborative_filtering import AccessAnomaly, AccessAnomalyModel, AccessAnomalyConfig, ConnectedComponents, ModelNormalizeTransformer, _UserResourceFeatureVectorMapping
  from synapsemltest.cyber.explain_tester import ExplainTester
  from synapsemltest.spark import *
label_desc: Use image node_id 2 for calling a global function with example usage: create_stats(df, tenant_col, value_col) and returns: StatsMap