code: def get_contrib_df(
      shap_base_value,
      shap_values,
      X_row,
      topx=None,
      cutoff=None,
      sort="abs",
      cols=None,
  ):
      """
      Return a contrib_df DataFrame that lists the SHAP contribution of each input
      variable for a single prediction, formatted in a way that makes it easy to
      plot a waterfall plot.
  
      Args:
          shap_base_value (float): the value of shap.Explainer.expected_value
          shap_values (np.ndarray): single array of shap values for a specific
              prediction, corresponding to X_row
          X_row (pd.DataFrame): a single row of data, generated with e.g. X.iloc[[index]]
          topx (int): only display the topx highest impact features.
          cutoff (float): only display features with a SHAP value of at least
              cutoff.
          sort ({'abs', 'high-to-low', 'low-to-high'}), sort the shap value
              contributions either from highest absolute shap to lowest absolute
              shap ('abs'), or from most positive to most negative ('high-to-low')
              or from most negative to most positive ('low-to-high'). Defaults
              to 'abs'.
          cols (list of str): particular list of columns to display, in that order. Will
              override topx, cutoff, sort, etc.
  
      Features below topx or cutoff are summed together under _REST. Final
      prediction is added as _PREDICTION.
  
      Returns:
          pd.DataFrame with columns=['col', 'contribution', 'value', 'cumulative', 'base']
      """
      assert isinstance(
          X_row, pd.DataFrame
      ), "X_row should be a pd.DataFrame! Use X.iloc[[index]]"
      assert (
          len(X_row.iloc[[0]].values[0].shape) == 1
      ), """X is not the right shape: len(X.values[0]) should be 1. 
              Try passing X.iloc[[index]]"""
      assert sort in {
          "abs",
          "high-to-low",
          "low-to-high",
          "importance",
          None,
      }
  
      # start with the shap_base_value
      base_df = pd.DataFrame(
          {
              "col": ["_BASE"],
              "contribution": [shap_base_value],
              "value": [""],
          }
      )
  
      contrib_df = pd.DataFrame(
          {
              "col": X_row.columns,
              "contribution": shap_values,
              "value": X_row.values[0],
          }
      )
      if cols is None:
          if cutoff is None and topx is not None:
              cutoff = (
                  contrib_df.contribution.abs().nlargest(topx).min()
              )
          elif cutoff is None and topx is None:
              cutoff = 0
  
          display_df = contrib_df[
              contrib_df.contribution.abs() >= cutoff
          ]
          if topx is not None and len(display_df) > topx:
              # in case of ties around cutoff
              display_df = display_df.reindex(
                  display_df.contribution.abs()
                  .sort_values(ascending=False)
                  .index
              ).head(topx)
  
          display_df_neg = display_df[display_df.contribution < 0]
          display_df_pos = display_df[display_df.contribution >= 0]
          print(
              contrib_df[~contrib_df.col.isin(display_df.col.tolist())]
          )
  
          rest_df = pd.DataFrame(
              {
                  "col": ["_REST"],
                  "contribution": [
                      contrib_df[
                          ~contrib_df.col.isin(display_df.col.tolist())
                      ]["contribution"].sum()
                  ],
                  "value": [""],
              }
          )
  
          # sort the df by absolute value from highest to lowest:
          if sort == "abs":
              display_df = display_df.reindex(
                  display_df.contribution.abs()
                  .sort_values(ascending=False)
                  .index
              )
              contrib_df = pd.concat(
                  [base_df, display_df, rest_df], ignore_index=True
              )
          if sort == "high-to-low":
              display_df_pos = display_df_pos.reindex(
                  display_df_pos.contribution.abs()
                  .sort_values(ascending=False)
                  .index
              )
              display_df_neg = display_df_neg.reindex(
                  display_df_neg.contribution.abs().sort_values().index
              )
              contrib_df = pd.concat(
                  [base_df, display_df_pos, rest_df, display_df_neg],
                  ignore_index=True,
              )
          if sort == "low-to-high":
              display_df_pos = display_df_pos.reindex(
                  display_df_pos.contribution.abs().sort_values().index
              )
              display_df_neg = display_df_neg.reindex(
                  display_df_neg.contribution.abs()
                  .sort_values(ascending=False)
                  .index
              )
              contrib_df = pd.concat(
                  [base_df, display_df_neg, rest_df, display_df_pos],
                  ignore_index=True,
              )
      else:
          display_df = (
              contrib_df[contrib_df.col.isin(cols)]
              .set_index("col")
              .reindex(cols)
              .reset_index()
          )
          rest_df = pd.DataFrame(
              {
                  "col": ["_REST"],
                  "contribution": [
                      contrib_df[~contrib_df.col.isin(cols)][
                          "contribution"
                      ].sum()
                  ],
                  "value": [""],
              }
          )
          contrib_df = pd.concat(
              [base_df, display_df, rest_df], ignore_index=True
          )
  
      # add cumulative contribution from top to bottom (for making bar chart):
      contrib_df["cumulative"] = contrib_df.contribution.cumsum()
      contrib_df["base"] = (
          contrib_df["cumulative"] - contrib_df["contribution"]
      )
  
      pred_df = (
          contrib_df[["contribution"]]
          .sum()
          .to_frame()
          .T.assign(
              col="_PREDICTION",
              value="",
              cumulative=lambda df: df.contribution,
              base=0,
          )
      )
      return pd.concat([contrib_df, pred_df], ignore_index=True)
  
imports: from functools import partial
  import re
  from collections import Counter
  from typing import List, Union
  import warnings
  import numpy
  import pandas
  from pandas.api.types import is_numeric_dtype, is_categorical_dtype
  from dtreeviz.trees import ShadowDecTree
  from sklearn.metrics import make_scorer
  from sklearn.base import clone
  from sklearn.pipeline import Pipeline
  from sklearn.model_selection import KFold, StratifiedKFold
  from joblib import Parallel, delayed
label_desc: Use image node_id 24 for calling a global function with example usage: get_contrib_df(shap_base_value, shap_values, X_row, topx, cutoff, sort, cols) and returns: pd