code: def group_by_columns(
      df: pd.DataFrame,
      columns: List[str],
      bins: int = 6,
      categorical_cols: List[str] = [],
  ):
      """
      Groups dataframe by the categories (or bucketized values) for all columns provided.
          If categorical it uses categories,
          if numeric, it uses bins. If more than one column is provided, the columns
          provided are, for example, age and binary_target_label, then the result
          would be a pandas DataFrame that is grouped by age groups for each of the
          positive and negative/positive labels.
  
      :Example:
  
      columns=["loan", "gender"]
      df_groups = xai.group_by_columns(
          df,
          columns=columns,
          bins=10,
          categorical_cols=["gender", "loan"])
  
      for group, df_group in df_groups:
          print(group)
          print(grouped_df.head())
  
      :param df: Pandas Dataframe containing data (inputs and target)
      :type df: pandas.DataFrame
      :param bins: [Default: 6] Number of bins to be used for numerical cols
      :type bins: int
      :param categorical_cols: [Default: []] Columns within dataframe that are
          categorical. Columns that are not np.objects or np.bool and
          are not part explicitly
          provided here will be treated as numeric, and bins will be used.
      :type categorical_cols: List[str]
      :returns: Dataframe with categorical numerical values.
      :rtype: pandas.core.groupby.groupby.DataFrameGroupBy
  
      """
  
      if not len(categorical_cols):
          categorical_cols = _infer_categorical(df)
  
      group_list = []
      for c in columns:
          col = df[c]
          if c in categorical_cols or not bins:
              grp = c
          else:
              col_min = col.min()
              col_max = col.max()
              # TODO: Use the original bins for display purposes as they may come normalised
              col_bins = pd.cut(
                  col, list(np.linspace(col_min, col_max, bins))
              )
              grp = col_bins
  
          group_list.append(grp)
  
      grouped = df.groupby(group_list)
      return grouped
  
imports: import pandas
  import matplotlib.pyplot
  import numpy
  from scipy.stats import spearmanr
  from scipy.cluster import hierarchy
  from typing import List, Any, Union, Tuple, Optional, Dict
  import random, math
  from sklearn.metrics import roc_curve, precision_recall_curve, roc_auc_score, confusion_matrix
  import itertools
  import logging
label_desc: Use image node_id 3 for calling a global function with example usage: group_by_columns(df, columns, bins, categorical_cols) and returns: grouped