code: def _finalize_gb_agg(
      gb_in,
      gb_cols,
      aggs,
      columns,
      final_columns,
      as_index,
      dropna,
      sort,
      sep,
      str_cols_out,
      aggs_renames,
  ):
      """Final aggregation task.
  
      This is the final operation on each output partitions
      of the `groupby_agg` algorithm.  This function must
      take care of higher-order aggregations, like "mean",
      "std" and "var".  We also need to deal with the column
      index, the row index, and final sorting behavior.
      """
  
      gb = _tree_node_agg(gb_in, gb_cols, dropna, sort, sep)
  
      # Deal with higher-order aggregations
      for col in columns:
          agg_list = aggs.get(col, [])
          agg_set = set(agg_list)
          if agg_set.intersection({"mean", "std", "var"}):
              count_name = _make_name((col, "count"), sep=sep)
              sum_name = _make_name((col, "sum"), sep=sep)
              if agg_set.intersection({"std", "var"}):
                  pow2_sum_name = _make_name(
                      (col, "pow2", "sum"), sep=sep
                  )
                  var = _var_agg(
                      gb, col, count_name, sum_name, pow2_sum_name
                  )
                  if "var" in agg_list:
                      name_var = _make_name((col, "var"), sep=sep)
                      gb[name_var] = var
                  if "std" in agg_list:
                      name_std = _make_name((col, "std"), sep=sep)
                      gb[name_std] = np.sqrt(var)
                  gb.drop(columns=[pow2_sum_name], inplace=True)
              if "mean" in agg_list:
                  mean_name = _make_name((col, "mean"), sep=sep)
                  gb[mean_name] = gb[sum_name] / gb[count_name]
              if "sum" not in agg_list:
                  gb.drop(columns=[sum_name], inplace=True)
              if "count" not in agg_list:
                  gb.drop(columns=[count_name], inplace=True)
          if "collect" in agg_list:
              collect_name = _make_name((col, "collect"), sep=sep)
              gb[collect_name] = gb[collect_name].list.concat()
  
      # Ensure sorted keys if `sort=True`
      if sort:
          gb = gb.sort_values(gb_cols)
  
      # Set index if necessary
      if as_index:
          gb.set_index(gb_cols, inplace=True)
  
      # Unflatten column names
      col_array = []
      agg_array = []
      for col in gb.columns:
          if col in gb_cols:
              col_array.append(col)
              agg_array.append("")
          else:
              name, agg = col.split(sep)
              col_array.append(name)
              agg_array.append(aggs_renames.get((name, agg), agg))
      if str_cols_out:
          gb.columns = col_array
      else:
          gb.columns = pd.MultiIndex.from_arrays([col_array, agg_array])
  
      return gb[final_columns]
  
imports: from functools import wraps
  from typing import Set
  import numpy
  import pandas
  from dask.dataframe.core import DataFrame, aca, split_out_on_cols
  from dask.dataframe.groupby import DataFrameGroupBy, SeriesGroupBy
  from dask.utils import funcname
  import cudf
  from cudf.utils.nvtx_annotation import _dask_cudf_nvtx_annotate
  from dask_cudf.sorting import _deprecate_shuffle_kwarg
label_desc: Use image node_id 12 for calling a global function with example usage: _finalize_gb_agg(gb_in, gb_cols, aggs, columns, final_columns, as_index, dropna, sort, sep, str_cols_out, aggs_renames) and returns: gb