code: def test_aggregator(self):
      df = self.df
      g = df.groupBy()
      self.assertEqual(
          [99, 100],
          sorted(g.agg({"key": "max", "value": "count"}).collect()[0]),
      )
      self.assertEqual(
          [Row(**{"AVG(key#0)": 49.5})], g.mean().collect()
      )
  
      from pyspark.sql import functions
  
      self.assertEqual(
          (0, "99"),
          tuple(
              g.agg(
                  functions.first(df.key), functions.last(df.value)
              ).first()
          ),
      )
      self.assertTrue(
          95 < g.agg(functions.approx_count_distinct(df.key)).first()[0]
      )
      # test deprecated countDistinct
      self.assertEqual(
          100, g.agg(functions.countDistinct(df.value)).first()[0]
      )
  
file_path: spark/python/pyspark/sql/tests/test_group.py
imports: import unittest
  from pyspark.sql import Row
  from pyspark.sql import functions
  from pyspark.testing.sqlutils import ReusedSQLTestCase, have_pandas, have_pyarrow, pandas_requirement_message, pyarrow_requirement_message
  from pyspark.testing import assertDataFrameEqual, assertSchemaEqual
label_desc: Use image node_id 2 for calling the GroupTestsMixin obj's underlying member method code with example usage: obj.test_aggregator() without return types