code: def groupby_apply(
      df: pd.DataFrame,
      cols: str | list[str],
      func: Callable[..., pd.DataFrame],
      *args: tuple[Any],
      **kwargs: Any,
  ) -> pd.DataFrame:
      """
      Groupby cols and call the function fn on each grouped dataframe.
  
      Parameters
      ----------
      cols : str | list of str
          columns to groupby
      func : callable
          function to call on the grouped data
      *args : tuple
          positional parameters to pass to func
      **kwargs : dict
          keyword parameter to pass to func
  
      This is meant to avoid pandas df.groupby('col').apply(fn, *args),
      as it calls fn twice on the first dataframe. If the nested code also
      does the same thing, it can be very expensive
      """
      if df.empty:
          return df.copy()
  
      try:
          axis = kwargs.pop("axis")
      except KeyError:
          axis = 0
  
      lst = []
      for _, d in df.groupby(cols, observed=True):
          # function fn should be free to modify dataframe d, therefore
          # do not mark d as a slice of df i.e no SettingWithCopyWarning
          lst.append(func(d, *args, **kwargs))
      return pd.concat(lst, axis=axis, ignore_index=True)
  
imports: from __future__ import annotations
  import inspect
  import itertools
  import warnings
  from collections import defaultdict
  from collections.abc import Iterable, Sequence
  from contextlib import suppress
  from typing import TYPE_CHECKING, cast, overload
  from warnings import warn
  import numpy
  import pandas
  from pandas.core.groupby import DataFrameGroupBy
  from ..exceptions import PlotnineError, PlotnineWarning
  from ..mapping import aes
label_desc: Use image node_id 19 for calling a global function with example usage: groupby_apply(df, cols, func) and returns: pd, df