code: def pivot_table(
      df, index=None, columns=None, values=None, aggfunc="mean"
  ):
      """
      Create a spreadsheet-style pivot table as a DataFrame. Target ``columns``
      must have category dtype to infer result's ``columns``.
      ``index``, ``columns``, and ``aggfunc`` must be all scalar.
      ``values`` can be scalar or list-like.
  
      Parameters
      ----------
      df : DataFrame
      index : scalar
          column to be index
      columns : scalar
          column to be columns
      values : scalar or list(scalar)
          column(s) to aggregate
      aggfunc : {'mean', 'sum', 'count', 'first', 'last'}, default 'mean'
  
      Returns
      -------
      table : DataFrame
  
      See Also
      --------
      pandas.DataFrame.pivot_table
      """
  
      if not is_scalar(index) or index is None:
          raise ValueError(
              "'index' must be the name of an existing column"
          )
      if not is_scalar(columns) or columns is None:
          raise ValueError(
              "'columns' must be the name of an existing column"
          )
      if not methods.is_categorical_dtype(df[columns]):
          raise ValueError("'columns' must be category dtype")
      if not has_known_categories(df[columns]):
          raise ValueError(
              "'columns' must have known categories. Please use "
              "`df[columns].cat.as_known()` beforehand to ensure "
              "known categories"
          )
      if not (
          is_list_like(values)
          and all([is_scalar(v) for v in values])
          or is_scalar(values)
      ):
          raise ValueError(
              "'values' must refer to an existing column or columns"
          )
  
      available_aggfuncs = ["mean", "sum", "count", "first", "last"]
  
      if not is_scalar(aggfunc) or aggfunc not in available_aggfuncs:
          raise ValueError(
              "aggfunc must be either "
              + ", ".join(f"'{x}'" for x in available_aggfuncs)
          )
  
      # _emulate can't work for empty data
      # the result must have CategoricalIndex columns
  
      columns_contents = pd.CategoricalIndex(
          df[columns].cat.categories, name=columns
      )
      if is_scalar(values):
          new_columns = columns_contents
      else:
          new_columns = pd.MultiIndex.from_product(
              (sorted(values), columns_contents), names=[None, columns]
          )
  
      if aggfunc in ["first", "last"]:
          # Infer datatype as non-numeric values are allowed
          if is_scalar(values):
              meta = pd.DataFrame(
                  columns=new_columns,
                  dtype=df[values].dtype,
                  index=pd.Index(df._meta[index]),
              )
          else:
              meta = pd.DataFrame(
                  columns=new_columns,
                  index=pd.Index(df._meta[index]),
              )
              for value_col in values:
                  meta[value_col] = meta[value_col].astype(
                      df[values].dtypes[value_col]
                  )
      else:
          # Use float64 as other aggregate functions require numerical data
          meta = pd.DataFrame(
              columns=new_columns,
              dtype=np.float64,
              index=pd.Index(df._meta[index]),
          )
  
      kwargs = {"index": index, "columns": columns, "values": values}
  
      if aggfunc in ["sum", "mean"]:
          pv_sum = apply_concat_apply(
              [df],
              chunk=methods.pivot_sum,
              aggregate=methods.pivot_agg,
              meta=meta,
              token="pivot_table_sum",
              chunk_kwargs=kwargs,
          )
  
      if aggfunc in ["count", "mean"]:
          pv_count = apply_concat_apply(
              [df],
              chunk=methods.pivot_count,
              aggregate=methods.pivot_agg,
              meta=meta,
              token="pivot_table_count",
              chunk_kwargs=kwargs,
          )
  
      if aggfunc == "sum":
          return pv_sum
      elif aggfunc == "count":
          return pv_count
      elif aggfunc == "mean":
          return pv_sum / pv_count
      elif aggfunc == "first":
          return apply_concat_apply(
              [df],
              chunk=methods.pivot_first,
              aggregate=methods.pivot_agg_first,
              meta=meta,
              token="pivot_table_first",
              chunk_kwargs=kwargs,
          )
      elif aggfunc == "last":
          return apply_concat_apply(
              [df],
              chunk=methods.pivot_last,
              aggregate=methods.pivot_agg_last,
              meta=meta,
              token="pivot_table_last",
              chunk_kwargs=kwargs,
          )
      else:
          raise ValueError
  
file_path: dask/dask/dataframe/reshape.py
imports: from __future__ import annotations
  import numpy
  import pandas
  from pandas.api.types import is_list_like, is_scalar
  import dask
  from dask.dataframe import methods
  from dask.dataframe._compat import PANDAS_GE_200
  from dask.dataframe.core import DataFrame, Series, apply_concat_apply, map_partitions
  from dask.dataframe.utils import has_known_categories
  from dask.typing import no_default
  from dask.utils import M, get_meta_library
label_desc: Use image node_id 2 for calling a global function with example usage: pivot_table(df, index, columns, values, aggfunc) and returns: pv_sum, pv_count, unknown, apply_concat_apply, apply_concat_apply