class_docstr: Hierarchical reconciliation transformer.
  
  Hierarchical reconciliation is a transformation which is used to make the
  predictions in a hierarchy of time-series sum together appropriately.
  
  The methods implemented in this class only require the structure of the
  hierarchy or the forecasts values for reconciliation.
  
  These functions are intended for transforming hierarchical forecasts, i.e.
  after prediction. However they are general and can be used to transform
  hierarchical time-series data.
  
  Please refer to [1]_ for further information
  
  Parameters
  ----------
  method : {"bu", "ols", "wls_str", "td_fcst"}, default="bu"
      The reconciliation approach applied to the forecasts
          "bu" - bottom-up
          "ols" - ordinary least squares
          "wls_str" - weighted least squares (structural)
          "td_fcst" - top down based on (forecast) proportions
  
  See Also
  --------
  Aggregator
  ReconcilerForecaster
  
  References
  ----------
  .. [1] https://otexts.com/fpp3/hierarchical.html
  
  Examples
  --------
  >>> from sktime.forecasting.trend import PolynomialTrendForecaster
  >>> from sktime.transformations.hierarchical.reconcile import Reconciler
  >>> from sktime.transformations.hierarchical.aggregate import Aggregator
  >>> from sktime.utils._testing.hierarchical import _bottom_hier_datagen
  >>> agg = Aggregator()
  >>> y = _bottom_hier_datagen(
  ...     no_bottom_nodes=3,
  ...     no_levels=1,
  ...     random_seed=123,
  ... )
  >>> y = agg.fit_transform(y)
  >>> forecaster = PolynomialTrendForecaster()
  >>> forecaster.fit(y)
  PolynomialTrendForecaster(...)
  >>> prds = forecaster.predict(fh=[1])
  >>> # reconcile forecasts
  >>> reconciler = Reconciler(method="ols")
  >>> prds_recon = reconciler.fit_transform(prds)
class_docstr_tok: ["Hierarchical","reconciliation","transformer",".","Hierarchical","reconciliation","is","a","transformation","which","is","used","to","make","the","predictions","in","a","hierarchy","of","time-series","sum","together","appropriately",".","The","methods","implemented","in","this","class","only","require","the","structure","of","the","hierarchy","or","the","forecasts","values","for","reconciliation",".","These","functions","are","intended","for","transforming","hierarchical","forecasts",",","i.e",".","after","prediction",".","However","they","are","general","and","can","be","used","to","transform","hierarchical","time-series","data",".","Please","refer","to","[","1","]","_","for","further","information","Parameters","--","--","--","--","--","method",":","{","``","bu","''",",","``","ols","''",",","``","wls_str","''",",","``","td_fcst","''","}",",","default=","''","bu","''","The","reconciliation","approach","applied","to","the","forecasts","``","bu","''","-","bottom-up","``","ols","''","-","ordinary","least","squares","``","wls_str","''","-","weighted","least","squares","(","structural",")","``","td_fcst","''","-","top","down","based","on","(","forecast",")","proportions","See","Also","--","--","--","--","Aggregator","ReconcilerForecaster","References","--","--","--","--","--","..","[","1","]","https",":","\/\/otexts.com\/fpp3\/hierarchical.html","Examples","--","--","--","--",">",">",">","from","sktime.forecasting.trend","import","PolynomialTrendForecaster",">",">",">","from","sktime.transformations.hierarchical.reconcile","import","Reconciler",">",">",">","from","sktime.transformations.hierarchical.aggregate","import","Aggregator",">",">",">","from","sktime.utils._testing.hierarchical","import","_bottom_hier_datagen",">",">",">","agg","=","Aggregator","(",")",">",">",">","y","=","_bottom_hier_datagen","(","...","no_bottom_nodes=3",",","...","no_levels=1",",","...","random_seed=123",",","...",")",">",">",">","y","=","agg.fit_transform","(","y",")",">",">",">","forecaster","=","PolynomialTrendForecaster","(",")",">",">",">","forecaster.fit","(","y",")","PolynomialTrendForecaster","(","...",")",">",">",">","prds","=","forecaster.predict","(","fh=","[","1","]",")",">",">",">","#","reconcile","forecasts",">",">",">","reconciler","=","Reconciler","(","method=","''","ols","''",")",">",">",">","prds_recon","=","reconciler.fit_transform","(","prds",")"]
docstr: Transform X and return a transformed version.
  
  private _transform containing core logic, called from transform
  
  Parameters
  ----------
  X : Panel of mtype pd_multiindex_hier
      Data to be transformed
  y : Ignored argument for interface compatibility.
  
  Returns
  -------
  recon_preds : multi-indexed pd.DataFrame of Panel mtype pd_multiindex
docstr_tok: ["Transform","X","and","return","a","transformed","version",".","private","_transform","containing","core","logic",",","called","from","transform","Parameters","--","--","--","--","--","X",":","Panel","of","mtype","pd_multiindex_hier","Data","to","be","transformed","y",":","Ignored","argument","for","interface","compatibility",".","Returns","--","--","--","-","recon_preds",":","multi-indexed","pd.DataFrame","of","Panel","mtype","pd_multiindex"]
code: def _transform(self, X, y=None):
      """Transform X and return a transformed version.
  
      private _transform containing core logic, called from transform
  
      Parameters
      ----------
      X : Panel of mtype pd_multiindex_hier
          Data to be transformed
      y : Ignored argument for interface compatibility.
  
      Returns
      -------
      recon_preds : multi-indexed pd.DataFrame of Panel mtype pd_multiindex
      """
      # check the length of index
      if X.index.nlevels < 2:
          warn(
              "Reconciler is intended for use with X.index.nlevels > 1. "
              "Returning X unchanged.",
              obj=self,
          )
          return X
  
      # check index for no "__total", if not add totals to X
      if _check_index_no_total(X):
          warn(
              "No elements of the index of X named '__total' found. Adding "
              "aggregate levels using the default Aggregator transformer "
              "before reconciliation.",
              obj=self,
          )
          X = self._add_totals(X)
  
      # check here that index of X matches the self.s_matrix
      al_inds = X.droplevel(level=-1).index.unique()
      chk_newindx = np.all(self.s_matrix.index == al_inds)
      if not chk_newindx:
          raise ValueError(
              "Check unique indexes of X.droplevel(level=-1) matches "
              "the data used in Reconciler().fit(X)."
          )
  
      X = X.groupby(level=-1)
      # could use X.transform() with np.dot, v. marginally faster in my tests
      # - loop can use index matching via df.dot() which is probably worth it
      recon_preds = []
      gmat = self.g_matrix
      for _name, group in X:
          if self.method == "td_fcst":
              gmat = _update_td_fcst(
                  g_matrix=gmat,
                  x_sf=group.droplevel(-1),
                  conn_df=self.parent_child,
              )
          # reconcile via SGy
          fcst = self.s_matrix.dot(gmat.dot(group.droplevel(-1)))
          # add back in time index
          fcst.index = group.index
          recon_preds.append(fcst)
  
      recon_preds = pd.concat(recon_preds, axis=0)
      recon_preds = recon_preds.sort_index()
  
      return recon_preds
  
imports: import numpy
  import pandas
  from numpy.linalg import inv
  from sktime.transformations.base import BaseTransformer
  from sktime.transformations.hierarchical.aggregate import _check_index_no_total
  from sktime.utils.warnings import warn
label_desc: Use image node_id 4 for calling the Reconciler obj's underlying member method code with example usage: obj._transform(X, y) and returns: recon_preds, X