class_docstr: Extended descriptive statistics for data
  
  Parameters
  ----------
  data : array_like
      Data to describe. Must be convertible to a pandas DataFrame.
  stats : Sequence[str], optional
      Statistics to include. If not provided the full set of statistics is
      computed. This list may evolve across versions to reflect best
      practices. Supported options are:
      "nobs", "missing", "mean", "std_err", "ci", "ci", "std", "iqr",
      "iqr_normal", "mad", "mad_normal", "coef_var", "range", "max",
      "min", "skew", "kurtosis", "jarque_bera", "mode", "freq",
      "median", "percentiles", "distinct", "top", and "freq". See Notes for
      details.
  numeric : bool, default True
      Whether to include numeric columns in the descriptive statistics.
  categorical : bool, default True
      Whether to include categorical columns in the descriptive statistics.
  alpha : float, default 0.05
      A number between 0 and 1 representing the size used to compute the
      confidence interval, which has coverage 1 - alpha.
  use_t : bool, default False
      Use the Student's t distribution to construct confidence intervals.
  percentiles : sequence[float]
      A distinct sequence of floating point values all between 0 and 100.
      The default percentiles are 1, 5, 10, 25, 50, 75, 90, 95, 99.
  ntop : int, default 5
      The number of top categorical labels to report. Default is
  
  Attributes
  ----------
  numeric_statistics
      The list of supported statistics for numeric data
  categorical_statistics
      The list of supported statistics for categorical data
  default_statistics
      The default list of statistics
  
  See Also
  --------
  pandas.DataFrame.describe
      Basic descriptive statistics
  describe
      A simplified version that returns a DataFrame
  
  Notes
  -----
  The selectable statistics include:
  
  * "nobs" - Number of observations
  * "missing" - Number of missing observations
  * "mean" - Mean
  * "std_err" - Standard Error of the mean assuming no correlation
  * "ci" - Confidence interval with coverage (1 - alpha) using the normal or
    t. This option creates two entries in any tables: lower_ci and upper_ci.
  * "std" - Standard Deviation
  * "iqr" - Interquartile range
  * "iqr_normal" - Interquartile range relative to a Normal
  * "mad" - Mean absolute deviation
  * "mad_normal" - Mean absolute deviation relative to a Normal
  * "coef_var" - Coefficient of variation
  * "range" - Range between the maximum and the minimum
  * "max" - The maximum
  * "min" - The minimum
  * "skew" - The skewness defined as the standardized 3rd central moment
  * "kurtosis" - The kurtosis defined as the standardized 4th central moment
  * "jarque_bera" - The Jarque-Bera test statistic for normality based on
    the skewness and kurtosis. This option creates two entries, jarque_bera
    and jarque_beta_pval.
  * "mode" - The mode of the data. This option creates two entries in all tables,
    mode and mode_freq which is the empirical frequency of the modal value.
  * "median" - The median of the data.
  * "percentiles" - The percentiles. Values included depend on the input value of
    ``percentiles``.
  * "distinct" - The number of distinct categories in a categorical.
  * "top" - The mode common categories. Labeled top_n for n in 1, 2, ..., ``ntop``.
  * "freq" - The frequency of the common categories. Labeled freq_n for n in 1,
    2, ..., ``ntop``.
class_docstr_tok: ["Extended","descriptive","statistics","for","data","Parameters","--","--","--","--","--","data",":","array_like","Data","to","describe",".","Must","be","convertible","to","a","pandas","DataFrame",".","stats",":","Sequence","[","str","]",",","optional","Statistics","to","include",".","If","not","provided","the","full","set","of","statistics","is","computed",".","This","list","may","evolve","across","versions","to","reflect","best","practices",".","Supported","options","are",":","``","nobs","''",",","``","missing","''",",","``","mean","''",",","``","std_err","''",",","``","ci","''",",","``","ci","''",",","``","std","''",",","``","iqr","''",",","``","iqr_normal","''",",","``","mad","''",",","``","mad_normal","''",",","``","coef_var","''",",","``","range","''",",","``","max","''",",","``","min","''",",","``","skew","''",",","``","kurtosis","''",",","``","jarque_bera","''",",","``","mode","''",",","``","freq","''",",","``","median","''",",","``","percentiles","''",",","``","distinct","''",",","``","top","''",",","and","``","freq","''",".","See","Notes","for","details",".","numeric",":","bool",",","default","True","Whether","to","include","numeric","columns","in","the","descriptive","statistics",".","categorical",":","bool",",","default","True","Whether","to","include","categorical","columns","in","the","descriptive","statistics",".","alpha",":","float",",","default","0.05","A","number","between","0","and","1","representing","the","size","used","to","compute","the","confidence","interval",",","which","has","coverage","1","-","alpha",".","use_t",":","bool",",","default","False","Use","the","Student","'s","t","distribution","to","construct","confidence","intervals",".","percentiles",":","sequence","[","float","]","A","distinct","sequence","of","floating","point","values","all","between","0","and","100",".","The","default","percentiles","are","1",",","5",",","10",",","25",",","50",",","75",",","90",",","95",",","99.","ntop",":","int",",","default","5","The","number","of","top","categorical","labels","to","report",".","Default","is","Attributes","--","--","--","--","--","numeric_statistics","The","list","of","supported","statistics","for","numeric","data","categorical_statistics","The","list","of","supported","statistics","for","categorical","data","default_statistics","The","default","list","of","statistics","See","Also","--","--","--","--","pandas.DataFrame.describe","Basic","descriptive","statistics","describe","A","simplified","version","that","returns","a","DataFrame","Notes","--","--","-","The","selectable","statistics","include",":","*","``","nobs","''","-","Number","of","observations","*","``","missing","''","-","Number","of","missing","observations","*","``","mean","''","-","Mean","*","``","std_err","''","-","Standard","Error","of","the","mean","assuming","no","correlation","*","``","ci","''","-","Confidence","interval","with","coverage","(","1","-","alpha",")","using","the","normal","or","t.","This","option","creates","two","entries","in","any","tables",":","lower_ci","and","upper_ci",".","*","``","std","''","-","Standard","Deviation","*","``","iqr","''","-","Interquartile","range","*","``","iqr_normal","''","-","Interquartile","range","relative","to","a","Normal","*","``","mad","''","-","Mean","absolute","deviation","*","``","mad_normal","''","-","Mean","absolute","deviation","relative","to","a","Normal","*","``","coef_var","''","-","Coefficient","of","variation","*","``","range","''","-","Range","between","the","maximum","and","the","minimum","*","``","max","''","-","The","maximum","*","``","min","''","-","The","minimum","*","``","skew","''","-","The","skewness","defined","as","the","standardized","3rd","central","moment","*","``","kurtosis","''","-","The","kurtosis","defined","as","the","standardized","4th","central","moment","*","``","jarque_bera","''","-","The","Jarque-Bera","test","statistic","for","normality","based","on","the","skewness","and","kurtosis",".","This","option","creates","two","entries",",","jarque_bera","and","jarque_beta_pval",".","*","``","mode","''","-","The","mode","of","the","data",".","This","option","creates","two","entries","in","all","tables",",","mode","and","mode_freq","which","is","the","empirical","frequency","of","the","modal","value",".","*","``","median","''","-","The","median","of","the","data",".","*","``","percentiles","''","-","The","percentiles",".","Values","included","depend","on","the","input","value","of","``","percentiles","``",".","*","``","distinct","''","-","The","number","of","distinct","categories","in","a","categorical",".","*","``","top","''","-","The","mode","common","categories",".","Labeled","top_n","for","n","in","1",",","2",",","...",",","``","ntop","``",".","*","``","freq","''","-","The","frequency","of","the","common","categories",".","Labeled","freq_n","for","n","in","1",",","2",",","...",",","``","ntop","``","."]
docstr: Descriptive statistics for numeric data
  
  Returns
  -------
  DataFrame
      The statistics of the numeric columns
docstr_tok: ["Descriptive","statistics","for","numeric","data","Returns","--","--","--","-","DataFrame","The","statistics","of","the","numeric","columns"]
code: def numeric(self) -> pd.DataFrame:
      """
      Descriptive statistics for numeric data
  
      Returns
      -------
      DataFrame
          The statistics of the numeric columns
      """
      df: pd.DataFrame = self._data.loc[:, self._is_numeric]
      cols = df.columns
      _, k = df.shape
      std = df.std()
      count = df.count()
      mean = df.mean()
      mad = (df - mean).abs().mean()
      std_err = std.copy()
      std_err.loc[count > 0] /= count.loc[count > 0] ** 0.5
      if self._use_t:
          q = stats.t(count - 1).ppf(1.0 - self._alpha / 2)
      else:
          q = stats.norm.ppf(1.0 - self._alpha / 2)
  
      def _mode(ser):
          dtype = (
              ser.dtype
              if isinstance(ser.dtype, np.dtype)
              else ser.dtype.numpy_dtype
          )
          ser_no_missing = ser.dropna().to_numpy(dtype=dtype)
          kwargs = {} if SP_LT_19 else {"keepdims": True}
          mode_res = stats.mode(ser_no_missing, **kwargs)
          # Changes in SciPy 1.10
          if np.isscalar(mode_res[0]):
              return float(mode_res[0]), mode_res[1]
          if mode_res[0].shape[0] > 0:
              return [float(val) for val in mode_res]
          return np.nan, np.nan
  
      mode_values = df.apply(_mode).T
      if mode_values.size > 0:
          if isinstance(mode_values, pd.DataFrame):
              # pandas 1.0 or later
              mode = np.asarray(mode_values[0], dtype=float)
              mode_counts = np.asarray(mode_values[1], dtype=np.int64)
          else:
              # pandas before 1.0 returns a Series of 2-elem list
              mode = []
              mode_counts = []
              for idx in mode_values.index:
                  val = mode_values.loc[idx]
                  mode.append(val[0])
                  mode_counts.append(val[1])
              mode = np.atleast_1d(mode)
              mode_counts = np.atleast_1d(mode_counts)
      else:
          mode = mode_counts = np.empty(0)
      loc = count > 0
      mode_freq = np.full(mode.shape[0], np.nan)
      mode_freq[loc] = mode_counts[loc] / count.loc[loc]
      # TODO: Workaround for pandas AbstractMethodError in extension
      #  types. Remove when quantile is supported for these
      _df = df
      try:
          from pandas.api.types import is_extension_array_dtype
  
          _df = df.copy()
          for col in df:
              if is_extension_array_dtype(df[col].dtype):
                  if _df[col].isnull().any():
                      _df[col] = _df[col].fillna(np.nan)
      except ImportError:
          pass
  
      if df.shape[1] > 0:
          iqr = _df.quantile(0.75) - _df.quantile(0.25)
      else:
          iqr = mean
  
      def _safe_jarque_bera(c):
          a = np.asarray(c)
          if a.shape[0] < 2:
              return (np.nan,) * 4
          return jarque_bera(a)
  
      jb = df.apply(
          lambda x: list(_safe_jarque_bera(x.dropna())),
          result_type="expand",
      ).T
      nan_mean = mean.copy()
      nan_mean.loc[nan_mean == 0] = np.nan
      coef_var = std / nan_mean
  
      results = {
          "nobs": pd.Series(
              np.ones(k, dtype=np.int64) * df.shape[0], index=cols
          ),
          "missing": df.shape[0] - count,
          "mean": mean,
          "std_err": std_err,
          "upper_ci": mean + q * std_err,
          "lower_ci": mean - q * std_err,
          "std": std,
          "iqr": iqr,
          "mad": mad,
          "coef_var": coef_var,
          "range": pd_ptp(df),
          "max": df.max(),
          "min": df.min(),
          "skew": jb[2],
          "kurtosis": jb[3],
          "iqr_normal": iqr / np.diff(stats.norm.ppf([0.25, 0.75])),
          "mad_normal": mad / np.sqrt(2 / np.pi),
          "jarque_bera": jb[0],
          "jarque_bera_pval": jb[1],
          "mode": pd.Series(mode, index=cols),
          "mode_freq": pd.Series(mode_freq, index=cols),
          "median": df.median(),
      }
      final = {k: v for k, v in results.items() if k in self._stats}
      results_df = pd.DataFrame(
          list(final.values()), columns=cols, index=list(final.keys())
      )
      if "percentiles" not in self._stats:
          return results_df
      # Pandas before 1.0 cannot handle empty DF
      if df.shape[1] > 0:
          # TODO: Remove when extension types support quantile
          perc = _df.quantile(self._percentiles / 100).astype(float)
      else:
          perc = pd.DataFrame(
              index=self._percentiles / 100, dtype=float
          )
      if np.all(np.floor(100 * perc.index) == (100 * perc.index)):
          perc.index = [f"{int(100 * idx)}%" for idx in perc.index]
      else:
          dupe = True
          scale = 100
          index = perc.index
          while dupe:
              scale *= 10
              idx = np.floor(scale * perc.index)
              if np.all(np.diff(idx) > 0):
                  dupe = False
          index = np.floor(scale * index) / (scale / 100)
          fmt = f"0.{len(str(scale//100))-1}f"
          output = f"{{0:{fmt}}}%"
          perc.index = [output.format(val) for val in index]
  
      # Add in the names of the percentiles to the output
      self._stats = self._stats + perc.index.tolist()
  
      return self._reorder(pd.concat([results_df, perc], axis=0))
  
imports: from statsmodels.compat.pandas import PD_LT_2, Appender, is_numeric_dtype
  from statsmodels.compat.scipy import SP_LT_19
  from typing import Union
  from collections.abc import Sequence
  import numpy
  import pandas
  from scipy import stats
  from statsmodels.iolib.table import SimpleTable
  from statsmodels.stats.stattools import jarque_bera
  from statsmodels.tools.decorators import cache_readonly
  from statsmodels.tools.docstring import Docstring, Parameter
  from statsmodels.tools.validation import array_like, bool_like, float_like, int_like
label_desc: Use image node_id 4 for calling the Description obj's underlying member method code with example usage: obj.numeric() and returns: self, np,  np, jarque_bera, results_df, float,  mode_res, unknown, unknown