code: def test_groupby_apply():
      df1 = pd.DataFrame(
          {
              "a": [3, 4, 5, 3, 5, 4, 1, 2, 3],
              "b": [1, 3, 4, 5, 6, 5, 4, 4, 4],
              "c": list("aabaaddce"),
          }
      )
  
      def apply_call_with_err(_):
          raise ValueError
  
      def apply_df(df):
          return df.sort_index()
  
      def apply_df_with_error(df):
          assert len(df) > 2
          return df.sort_index()
  
      def apply_series(s):
          return s.sort_index()
  
      mdf = md.DataFrame(df1, chunk_size=3)
  
      # when dtype and output_type specified, apply function
      # shall not be called
      applied = mdf.groupby("b").apply(
          apply_call_with_err, output_type="series", dtype=int
      )
      assert applied.dtype == int
      assert applied.op.output_types[0] == OutputType.series
  
      with pytest.raises(TypeError):
          mdf.groupby("b").apply(apply_df_with_error)
  
      applied = tile(
          mdf.groupby("b").apply(
              apply_df_with_error,
              output_type="dataframe",
              dtypes=df1.dtypes,
          )
      )
      pd.testing.assert_series_equal(applied.dtypes, df1.dtypes)
      assert applied.shape == (np.nan, 3)
      assert applied.op._op_type_ == opcodes.APPLY
      assert applied.op.output_types[0] == OutputType.dataframe
      assert len(applied.chunks) == 3
      assert applied.chunks[0].shape == (np.nan, 3)
      pd.testing.assert_series_equal(
          applied.chunks[0].dtypes, df1.dtypes
      )
  
      applied = tile(mdf.groupby("b").apply(apply_df))
      pd.testing.assert_series_equal(applied.dtypes, df1.dtypes)
      assert applied.shape == (np.nan, 3)
      assert applied.op._op_type_ == opcodes.APPLY
      assert applied.op.output_types[0] == OutputType.dataframe
      assert len(applied.chunks) == 3
      assert applied.chunks[0].shape == (np.nan, 3)
      pd.testing.assert_series_equal(
          applied.chunks[0].dtypes, df1.dtypes
      )
  
      applied = tile(mdf.groupby("b").apply(lambda df: df.a))
      assert applied.dtype == df1.a.dtype
      assert applied.shape == (np.nan,)
      assert applied.op._op_type_ == opcodes.APPLY
      assert applied.op.output_types[0] == OutputType.series
      assert len(applied.chunks) == 3
      assert applied.chunks[0].shape == (np.nan,)
      assert applied.chunks[0].dtype == df1.a.dtype
  
      applied = mdf.groupby("b").apply(lambda df: df.a.sum())
      assert applied.op.maybe_agg is True
      # force set to pass test
      applied.op.maybe_agg = None
      applied = tile(applied)
      assert applied.dtype == df1.a.dtype
      assert applied.shape == (np.nan,)
      assert applied.op._op_type_ == opcodes.APPLY
      assert applied.op.output_types[0] == OutputType.series
      assert len(applied.chunks) == 3
      assert applied.chunks[0].shape == (np.nan,)
      assert applied.chunks[0].dtype == df1.a.dtype
  
      series1 = pd.Series([3, 4, 5, 3, 5, 4, 1, 2, 3])
  
      ms1 = md.Series(series1, chunk_size=3)
      applied = tile(ms1.groupby(lambda x: x % 3).apply(apply_series))
      assert applied.dtype == series1.dtype
      assert applied.shape == (np.nan,)
      assert applied.op._op_type_ == opcodes.APPLY
      assert applied.op.output_types[0] == OutputType.series
      assert len(applied.chunks) == 3
      assert applied.chunks[0].shape == (np.nan,)
      assert applied.chunks[0].dtype == series1.dtype
  
imports: from collections import OrderedDict
  import numpy
  import pandas
  import pytest
  from ..sort import DataFrameGroupbySortShuffle
  from ....None import dataframe
  from ....None import opcodes
  from ....config import option_context
  from ....core import OutputType, tile
  from ....core.operand import OperandStage
  from ...core import DataFrameGroupBy, SeriesGroupBy, DataFrame
  from ..core import DataFrameGroupByOperand, DataFrameShuffleProxy
  from ..aggregation import DataFrameGroupByAgg
  from ..getitem import GroupByIndex
label_desc: Use image node_id 5 for calling a global function with example usage: test_groupby_apply() and returns: df, df, s