code: def summary(
      data,
      var_names: Optional[List[str]] = None,
      filter_vars=None,
      group=None,
      fmt: "Literal['wide', 'long', 'xarray']" = "wide",
      kind: "Literal['all', 'stats', 'diagnostics']" = "all",
      round_to=None,
      circ_var_names=None,
      stat_focus="mean",
      stat_funcs=None,
      extend=True,
      hdi_prob=None,
      skipna=False,
      labeller=None,
      coords=None,
      index_origin=None,
      order=None,
  ) -> Union[pd.DataFrame, xr.Dataset]:
      """Create a data frame with summary statistics.
  
      Parameters
      ----------
      data: obj
          Any object that can be converted to an :class:`arviz.InferenceData` object
          Refer to documentation of :func:`arviz.convert_to_dataset` for details
      var_names: list
          Names of variables to include in summary. Prefix the variables by ``~`` when you
          want to exclude them from the summary: `["~beta"]` instead of `["beta"]` (see
          examples below).
      filter_vars: {None, "like", "regex"}, optional, default=None
          If `None` (default), interpret var_names as the real variables names. If "like",
          interpret var_names as substrings of the real variables names. If "regex",
          interpret var_names as regular expressions on the real variables names. A la
          ``pandas.filter``.
      coords: Dict[str, List[Any]], optional
          Coordinate subset for which to calculate the summary.
      group: str
          Select a group for summary. Defaults to "posterior", "prior" or first group
          in that order, depending what groups exists.
      fmt: {'wide', 'long', 'xarray'}
          Return format is either pandas.DataFrame {'wide', 'long'} or xarray.Dataset {'xarray'}.
      kind: {'all', 'stats', 'diagnostics'}
          Whether to include the `stats`: `mean`, `sd`, `hdi_3%`, `hdi_97%`, or the `diagnostics`:
          `mcse_mean`, `mcse_sd`, `ess_bulk`, `ess_tail`, and `r_hat`. Default to include `all` of
          them.
      round_to: int
          Number of decimals used to round results. Defaults to 2. Use "none" to return raw numbers.
      circ_var_names: list
          A list of circular variables to compute circular stats for
      stat_focus : str, default "mean"
          Select the focus for summary.
      stat_funcs: dict
          A list of functions or a dict of functions with function names as keys used to calculate
          statistics. By default, the mean, standard deviation, simulation standard error, and
          highest posterior density intervals are included.
  
          The functions will be given one argument, the samples for a variable as an nD array,
          The functions should be in the style of a ufunc and return a single number. For example,
          :func:`numpy.mean`, or ``scipy.stats.var`` would both work.
      extend: boolean
          If True, use the statistics returned by ``stat_funcs`` in addition to, rather than in place
          of, the default statistics. This is only meaningful when ``stat_funcs`` is not None.
      hdi_prob: float, optional
          Highest density interval to compute. Defaults to 0.94. This is only meaningful when
          ``stat_funcs`` is None.
      skipna: bool
          If true ignores nan values when computing the summary statistics, it does not affect the
          behaviour of the functions passed to ``stat_funcs``. Defaults to false.
      labeller : labeller instance, optional
          Class providing the method `make_label_flat` to generate the labels in the plot titles.
          For more details on ``labeller`` usage see :ref:`label_guide`
      credible_interval: float, optional
          deprecated: Please see hdi_prob
      order
          deprecated: order is now ignored.
      index_origin
          deprecated: index_origin is now ignored, modify the coordinate values to change the
          value used in summary.
  
      Returns
      -------
      pandas.DataFrame or xarray.Dataset
          Return type dicated by `fmt` argument.
  
          Return value will contain summary statistics for each variable. Default statistics depend on
          the value of ``stat_focus``:
  
          ``stat_focus="mean"``: `mean`, `sd`, `hdi_3%`, `hdi_97%`, `mcse_mean`, `mcse_sd`,
          `ess_bulk`, `ess_tail`, and `r_hat`
  
          ``stat_focus="median"``: `median`, `mad`, `eti_3%`, `eti_97%`, `mcse_median`, `ess_median`,
          `ess_tail`, and `r_hat`
  
          `r_hat` is only computed for traces with 2 or more chains.
  
      See Also
      --------
      waic : Compute the widely applicable information criterion.
      loo : Compute Pareto-smoothed importance sampling leave-one-out
            cross-validation (PSIS-LOO-CV).
      ess : Calculate estimate of the effective sample size (ess).
      rhat : Compute estimate of rank normalized splitR-hat for a set of traces.
      mcse : Calculate Markov Chain Standard Error statistic.
  
      Examples
      --------
      .. ipython::
  
          In [1]: import arviz as az
             ...: data = az.load_arviz_data("centered_eight")
             ...: az.summary(data, var_names=["mu", "tau"])
  
      You can use ``filter_vars`` to select variables without having to specify all the exact
      names. Use ``filter_vars="like"`` to select based on partial naming:
  
      .. ipython::
  
          In [1]: az.summary(data, var_names=["the"], filter_vars="like")
  
      Use ``filter_vars="regex"`` to select based on regular expressions, and prefix the variables
      you want to exclude by ``~``. Here, we exclude from the summary all the variables
      starting with the letter t:
  
      .. ipython::
  
          In [1]: az.summary(data, var_names=["~^t"], filter_vars="regex")
  
      Other statistics can be calculated by passing a list of functions
      or a dictionary with key, function pairs.
  
      .. ipython::
  
          In [1]: import numpy as np
             ...: def median_sd(x):
             ...:     median = np.percentile(x, 50)
             ...:     sd = np.sqrt(np.mean((x-median)**2))
             ...:     return sd
             ...:
             ...: func_dict = {
             ...:     "std": np.std,
             ...:     "median_std": median_sd,
             ...:     "5%": lambda x: np.percentile(x, 5),
             ...:     "median": lambda x: np.percentile(x, 50),
             ...:     "95%": lambda x: np.percentile(x, 95),
             ...: }
             ...: az.summary(
             ...:     data,
             ...:     var_names=["mu", "tau"],
             ...:     stat_funcs=func_dict,
             ...:     extend=False
             ...: )
  
      Use ``stat_focus`` to change the focus of summary statistics obatined to median:
  
      .. ipython::
  
          In [1]: az.summary(data, stat_focus="median")
  
      """
      _log.cache = []
  
      if coords is None:
          coords = {}
  
      if index_origin is not None:
          warnings.warn(
              "index_origin has been deprecated. summary now shows coordinate values, "
              "to change the label shown, modify the coordinate values before calling summary",
              DeprecationWarning,
          )
          index_origin = rcParams["data.index_origin"]
      if labeller is None:
          labeller = BaseLabeller()
      if hdi_prob is None:
          hdi_prob = rcParams["stats.hdi_prob"]
      elif not 1 >= hdi_prob > 0:
          raise ValueError(
              "The value of hdi_prob should be in the interval (0, 1]"
          )
  
      if isinstance(data, InferenceData):
          if group is None:
              if not data.groups():
                  raise TypeError(
                      "InferenceData does not contain any groups"
                  )
              if "posterior" in data:
                  dataset = data["posterior"]
              elif "prior" in data:
                  dataset = data["prior"]
              else:
                  warnings.warn(
                      f"Selecting first found group: {data.groups()[0]}"
                  )
                  dataset = data[data.groups()[0]]
          elif group in data.groups():
              dataset = data[group]
          else:
              raise TypeError(
                  f"InferenceData does not contain group: {group}"
              )
      else:
          dataset = convert_to_dataset(data, group="posterior")
      var_names = _var_names(var_names, dataset, filter_vars)
      dataset = dataset if var_names is None else dataset[var_names]
      dataset = get_coords(dataset, coords)
  
      fmt_group = ("wide", "long", "xarray")
      if not isinstance(fmt, str) or (fmt.lower() not in fmt_group):
          raise TypeError(
              f"Invalid format: '{fmt}'. Formatting options are: {fmt_group}"
          )
  
      kind_group = ("all", "stats", "diagnostics")
      if not isinstance(kind, str) or kind not in kind_group:
          raise TypeError(
              f"Invalid kind: '{kind}'. Kind options are: {kind_group}"
          )
  
      focus_group = ("mean", "median")
      if not isinstance(stat_focus, str) or (
          stat_focus not in focus_group
      ):
          raise TypeError(
              f"Invalid format: '{stat_focus}'. Focus options are: {focus_group}"
          )
  
      if stat_focus != "mean" and circ_var_names is not None:
          raise TypeError(
              f"Invalid format: Circular stats not supported for '{stat_focus}'"
          )
  
      if order is not None:
          warnings.warn(
              "order has been deprecated. summary now shows coordinate values.",
              DeprecationWarning,
          )
  
      alpha = 1 - hdi_prob
  
      extra_metrics = []
      extra_metric_names = []
  
      if stat_funcs is not None:
          if isinstance(stat_funcs, dict):
              for stat_func_name, stat_func in stat_funcs.items():
                  extra_metrics.append(
                      xr.apply_ufunc(
                          _make_ufunc(stat_func),
                          dataset,
                          input_core_dims=(("chain", "draw"),),
                      )
                  )
                  extra_metric_names.append(stat_func_name)
          else:
              for stat_func in stat_funcs:
                  extra_metrics.append(
                      xr.apply_ufunc(
                          _make_ufunc(stat_func),
                          dataset,
                          input_core_dims=(("chain", "draw"),),
                      )
                  )
                  extra_metric_names.append(stat_func.__name__)
  
      metrics: List[xr.Dataset] = []
      metric_names: List[str] = []
      if extend and kind in ["all", "stats"]:
          if stat_focus == "mean":
              mean = dataset.mean(dim=("chain", "draw"), skipna=skipna)
  
              sd = dataset.std(
                  dim=("chain", "draw"), ddof=1, skipna=skipna
              )
  
              hdi_post = hdi(
                  dataset,
                  hdi_prob=hdi_prob,
                  multimodal=False,
                  skipna=skipna,
              )
              hdi_lower = hdi_post.sel(hdi="lower", drop=True)
              hdi_higher = hdi_post.sel(hdi="higher", drop=True)
              metrics.extend((mean, sd, hdi_lower, hdi_higher))
              metric_names.extend(
                  (
                      "mean",
                      "sd",
                      f"hdi_{100 * alpha / 2:g}%",
                      f"hdi_{100 * (1 - alpha / 2):g}%",
                  )
              )
          elif stat_focus == "median":
              median = dataset.median(
                  dim=("chain", "draw"), skipna=skipna
              )
  
              mad = stats.median_abs_deviation(
                  dataset, dims=("chain", "draw")
              )
              eti_post = dataset.quantile(
                  (alpha / 2, 1 - alpha / 2),
                  dim=("chain", "draw"),
                  skipna=skipna,
              )
              eti_lower = eti_post.isel(quantile=0, drop=True)
              eti_higher = eti_post.isel(quantile=1, drop=True)
              metrics.extend((median, mad, eti_lower, eti_higher))
              metric_names.extend(
                  (
                      "median",
                      "mad",
                      f"eti_{100 * alpha / 2:g}%",
                      f"eti_{100 * (1 - alpha / 2):g}%",
                  )
              )
  
      if circ_var_names:
          nan_policy = "omit" if skipna else "propagate"
          circ_mean = stats.circmean(
              dataset,
              dims=["chain", "draw"],
              high=np.pi,
              low=-np.pi,
              nan_policy=nan_policy,
          )
          _numba_flag = Numba.numba_flag
          if _numba_flag:
              circ_sd = xr.apply_ufunc(
                  _make_ufunc(_circular_standard_deviation),
                  dataset,
                  kwargs=dict(high=np.pi, low=-np.pi, skipna=skipna),
                  input_core_dims=(("chain", "draw"),),
              )
          else:
              circ_sd = stats.circstd(
                  dataset,
                  dims=["chain", "draw"],
                  high=np.pi,
                  low=-np.pi,
                  nan_policy=nan_policy,
              )
          circ_mcse = xr.apply_ufunc(
              _make_ufunc(_mc_error),
              dataset,
              kwargs=dict(circular=True),
              input_core_dims=(("chain", "draw"),),
          )
  
          circ_hdi = hdi(
              dataset, hdi_prob=hdi_prob, circular=True, skipna=skipna
          )
          circ_hdi_lower = circ_hdi.sel(hdi="lower", drop=True)
          circ_hdi_higher = circ_hdi.sel(hdi="higher", drop=True)
  
      if kind in ["all", "diagnostics"] and extend:
          diagnostics_names: Tuple[str, ...]
          if stat_focus == "mean":
              diagnostics = xr.apply_ufunc(
                  _make_ufunc(
                      _multichain_statistics, n_output=5, ravel=False
                  ),
                  dataset,
                  input_core_dims=(("chain", "draw"),),
                  output_core_dims=tuple([] for _ in range(5)),
              )
              diagnostics_names = (
                  "mcse_mean",
                  "mcse_sd",
                  "ess_bulk",
                  "ess_tail",
                  "r_hat",
              )
  
          elif stat_focus == "median":
              diagnostics = xr.apply_ufunc(
                  _make_ufunc(
                      _multichain_statistics, n_output=4, ravel=False
                  ),
                  dataset,
                  kwargs=dict(focus="median"),
                  input_core_dims=(("chain", "draw"),),
                  output_core_dims=tuple([] for _ in range(4)),
              )
              diagnostics_names = (
                  "mcse_median",
                  "ess_median",
                  "ess_tail",
                  "r_hat",
              )
          metrics.extend(diagnostics)
          metric_names.extend(diagnostics_names)
  
      if (
          circ_var_names
          and kind != "diagnostics"
          and stat_focus == "mean"
      ):
          for metric, circ_stat in zip(
              # Replace only the first 5 statistics for their circular equivalent
              metrics[:5],
              (
                  circ_mean,
                  circ_sd,
                  circ_hdi_lower,
                  circ_hdi_higher,
                  circ_mcse,
              ),
          ):
              for circ_var in circ_var_names:
                  metric[circ_var] = circ_stat[circ_var]
  
      metrics.extend(extra_metrics)
      metric_names.extend(extra_metric_names)
      joined = (
          xr.concat(metrics, dim="metric")
          .assign_coords(metric=metric_names)
          .reset_coords(drop=True)
      )
      n_metrics = len(metric_names)
      n_vars = np.sum(
          [joined[var].size // n_metrics for var in joined.data_vars]
      )
  
      if fmt.lower() == "wide":
          summary_df = pd.DataFrame(
              (np.full((cast(int, n_vars), n_metrics), np.nan)),
              columns=metric_names,
          )
          indices = []
          for i, (var_name, sel, isel, values) in enumerate(
              xarray_var_iter(joined, skip_dims={"metric"})
          ):
              summary_df.iloc[i] = values
              indices.append(
                  labeller.make_label_flat(var_name, sel, isel)
              )
          summary_df.index = indices
      elif fmt.lower() == "long":
          df = joined.to_dataframe().reset_index().set_index("metric")
          df.index = list(df.index)
          summary_df = df
      else:
          # format is 'xarray'
          summary_df = joined
      if (round_to is not None) and (round_to not in ("None", "none")):
          summary_df = summary_df.round(round_to)
      elif round_to not in ("None", "none") and (
          fmt.lower() in ("long", "wide")
      ):
          # Don't round xarray object by default (even with "none")
          decimals = {
              col: 3
              if col not in {"ess_bulk", "ess_tail", "r_hat"}
              else 2
              if col == "r_hat"
              else 0
              for col in summary_df.columns
          }
          summary_df = summary_df.round(decimals)
  
      return summary_df
  
imports: import itertools
  import warnings
  from copy import deepcopy
  from typing import List, Optional, Tuple, Union, Mapping, cast, Callable
  import numpy
  import pandas
  import scipy.stats
  from xarray_einstats import stats
  import xarray
  from scipy.optimize import minimize
  from typing_extensions import Literal
  from ..None import _log
  from ..data import InferenceData, convert_to_dataset, convert_to_inference_data, extract
  from ..rcparams import rcParams, ScaleKeyword, ICKeyword
  from ..utils import Numba, _numba_var, _var_names, get_coords
  from .density_utils import get_bins
  from .density_utils import histogram
  from .density_utils import kde
  from .diagnostics import _mc_error, _multichain_statistics, ess
  from .stats_utils import ELPDData, _circular_standard_deviation, smooth_data
  from .stats_utils import get_log_likelihood
  from .stats_utils import get_log_prior
  from .stats_utils import logsumexp
  from .stats_utils import make_ufunc
  from .stats_utils import stats_variance_2d
  from .stats_utils import wrap_xarray_ufunc
  from ..sel_utils import xarray_var_iter
  from ..labels import BaseLabeller
label_desc: Use image node_id 14 for calling a global function with example usage: summary(data, var_names, filter_vars, group, fmt, kind, round_to, circ_var_names, stat_focus, stat_funcs, extend, hdi_prob, skipna, labeller, coords, index_origin, order) and returns: summary_df