code: def group_textblocks_based_on_category(
      layout: Iterable[TextBlock], union_group: bool = True
  ) -> Union[List[TextBlock], List[List[TextBlock]]]:
      """Group textblocks based on their category (block.type).
  
      Args:
          layout (Iterable):
              A list (or Layout) of BaseLayoutElement
          union_group (bool):
              Whether to union the boxes within each group.
              Defaults to True.
  
      Returns:
          List[TextBlock]: When `union_group=True`, it produces a list of
              TextBlocks, denoting the boundaries of each texblock group.
          List[List[TextBlock]]: When `union_group=False`, it preserves
              the elements within each group for further processing.
      """
  
      if union_group:
          aggregation_func = lambda seq: reduce(
              layout[0].__class__.union, seq
          )
      else:
          aggregation_func = None
  
      detected_group_boxes = (
          generalized_connected_component_analysis_1d(
              layout,
              scoring_func=lambda a, b: a.type == b.type,
              aggregation_func=aggregation_func,
          )
      )
  
      return detected_group_boxes
  
file_path: layout-parser/src/layoutparser/tools/shape_operations.py
imports: from typing import List, Union, Any, Callable, Iterable
  from functools import partial, reduce
  import numpy
  from scipy.sparse import csr_matrix
  from scipy.sparse.csgraph import connected_components
  from ..elements import BaseLayoutElement, TextBlock
label_desc: Use image node_id 3 for calling a global function with example usage: group_textblocks_based_on_category(layout, union_group) and returns: detected_group_boxes