class_docstr: Generate profiles of histograms using default statistical functions.
  
  Profiles are:
  
  - 1 dim histograms, all: 'count', 'filled', 'distinct', 'nan', 'most_probable_value', 'overflow', 'underflow'.
  - 1 dim histograms, numeric: mean, std, min, max, p01, p05, p16, p50, p84, p95, p99.
  - 1 dim histograms, boolean: fraction of true entries.
  - 2 dim histograms: count, phi_k correlation constant, p-value and Z-score of contingency test.
  - n dim histograms: count (n >= 3)
  
  :param str read_key: key of the input test data to read from the datastore
  :param str store_key: key of the output data to store in the datastore
  :param list features: features of data-frames to pick up from input data (optional)
  :param list ignore_features: features to ignore (optional)
  :param list var_timestamp: list of timestamp variables (optional)
  :param str hist_col: key for histogram in split dictionary
  :param str index_col: key for index in split dictionary
  :param dict stats_functions: function_name, function(bin_labels, bin_counts) dictionary
class_docstr_tok: ["Generate","profiles","of","histograms","using","default","statistical","functions",".","Profiles","are",":","-","1","dim","histograms",",","all",":","'count","'",",","'filled","'",",","'distinct","'",",","'nan","'",",","'most_probable_value","'",",","'overflow","'",",","'underflow","'",".","-","1","dim","histograms",",","numeric",":","mean",",","std",",","min",",","max",",","p01",",","p05",",","p16",",","p50",",","p84",",","p95",",","p99",".","-","1","dim","histograms",",","boolean",":","fraction","of","true","entries",".","-","2","dim","histograms",":","count",",","phi_k","correlation","constant",",","p-value","and","Z-score","of","contingency","test",".","-","n","dim","histograms",":","count","(","n",">","=","3",")",":","param","str","read_key",":","key","of","the","input","test","data","to","read","from","the","datastore",":","param","str","store_key",":","key","of","the","output","data","to","store","in","the","datastore",":","param","list","features",":","features","of","data-frames","to","pick","up","from","input","data","(","optional",")",":","param","list","ignore_features",":","features","to","ignore","(","optional",")",":","param","list","var_timestamp",":","list","of","timestamp","variables","(","optional",")",":","param","str","hist_col",":","key","for","histogram","in","split","dictionary",":","param","str","index_col",":","key","for","index","in","split","dictionary",":","param","dict","stats_functions",":","function_name",",","function","(","bin_labels",",","bin_counts",")","dictionary"]
code: def _profile_hist(self, split, hist_name):
      from popmon.analysis.profiling import Profiles
  
      if len(split) == 0:
          self.logger.error(
              f'Split histograms dict "{hist_name}" is empty. Return.'
          )
          return []
  
      hist0 = split[0][self.hist_col]
      dimension = hist0.n_dim
      is_num = is_numeric(hist0)
      htype = "num" if is_num else "cat"
  
      # these are the profiled quantities we will monitor
      expected_fields = (
          Profiles.get_keys_by_dim_and_htype(dim=dimension, htype=htype)
          + Profiles.get_keys_by_dim_and_htype(
              dim=dimension, htype="all"
          )
          + Profiles.get_keys_by_dim_and_htype(
              dim=dimension, htype=None
          )
      )
  
      # profiles regardless of dim and htype (e.g. count)
      expected_fields += Profiles.get_keys_by_dim_and_htype(
          dim=None, htype=None
      )
  
      # profiles regardless of dim
      expected_fields += Profiles.get_keys_by_dim_and_htype(
          dim=-1, htype=htype
      )
      expected_fields += Profiles.get_keys_by_dim_and_htype(
          dim=-1, htype="all"
      )
      expected_fields += Profiles.get_keys_by_dim_and_htype(
          dim=-1, htype=None
      )
  
      expected_fields += [self.index_col, self.hist_col]
  
      # now loop over split-axis, e.g. time index, and profile each sub-hist x:y
      profile_list = []
      for hist_dict in split:
          index, hist = (
              hist_dict[self.index_col],
              hist_dict[self.hist_col],
          )
  
          profile = {self.index_col: index, self.hist_col: hist}
  
          if dimension == 1:
              profile.update(
                  self._profile_1d_histogram(hist_name, hist)
              )
          else:
              profile.update(
                  self._profile_nd_histogram(
                      hist_name, hist, dim=dimension
                  )
              )
  
          if sorted(profile.keys()) != sorted(expected_fields):
              self.logger.error(
                  f'Could not extract full profile for sub-hist "{hist_name} {index}".'
                  f"Differences: {set(profile.keys()).symmetric_difference(set(expected_fields))}. Skipping."
              )
          else:
              profile_list.append(profile)
  
      return profile_list
  
file_path: popmon/popmon/analysis/profiling/hist_profiler.py
imports: import numpy
  import pandas
  from popmon.base import Module
  from popmon.hist.hist_utils import get_bin_centers, is_numeric, is_timestamp
label_desc: Use image node_id 4 for calling the HistProfiler obj's underlying member method code with example usage: obj._profile_hist(split, hist_name) and returns: profile_list, list