class_docstr: Missing value imputation.
  
  The Imputer transforms input series by replacing missing values according
  to an imputation strategy specified by `method`.
  
  Parameters
  ----------
  method : str, default="drift"
      Method to fill the missing values.
  
      * "drift" : drift/trend values by sktime.PolynomialTrendForecaster(degree=1)
          first, X in transform() is filled with ffill then bfill
          then PolynomialTrendForecaster(degree=1) is fitted to filled X, and
          predict values are queried at indices which had missing values
      * "linear" : linear interpolation, uses pd.Series.interpolate()
          WARNING: This method can not extrapolate, so it is fitted always on the
          data given to transform().
      * "nearest" : use nearest value, uses pd.Series.interpolate()
      * "constant" : same constant value (given in arg value) for all NaN
      * "mean" : pd.Series.mean() of *fit* data
      * "median" : pd.Series.median() of *fit* data
      * "backfill" to "bfill" : adapted from pd.Series.fillna()
      * "pad" or "ffill" : adapted from pd.Series.fillna()
      * "random" : random values between pd.Series.min() and .max() of *fit* data
          if pd.Series dtype is int, sample is uniform discrete
          if pd.Series dtype is float, sample is uniform continuous
      * "forecaster" : use an sktime Forecaster, given in param forecaster.
          First, X in *fit* is filled with ffill then bfill
          then forecaster is fitted to filled X, and *predict* values are queried
          at indices of X data in *transform* which had missing values
      For the following methods, the train data is used to fit them:
      "drift", "mean", "median", "random". For all other methods, the
      transform data is sufficient to compute the impute values.
  
  missing_values : int/float/str, default=None
      The placeholder for the missing values. All occurrences of
      missing_values will be imputed, in addition to np.nan.
      If None, then only np.nan values are imputed.
  value : int/float, default=None
      Value to use to fill missing values when method="constant".
  forecaster : Any Forecaster based on sktime.BaseForecaster, default=None
      Use a given Forecaster to impute by insample predictions when
      method="forecaster". Before fitting, missing data is imputed with
      method="ffill" or "bfill" as heuristic. in case of multivariate X,
      the forecaster is applied separate to each column like a
      ColumnEnsembleForecaster.
  random_state : int/float/str, optional
      Value to set random.seed() if method="random", default None
  
  Examples
  --------
  >>> from sktime.transformations.series.impute import Imputer
  >>> from sktime.datasets import load_airline
  >>> from sktime.split import temporal_train_test_split
  >>> y = load_airline()
  >>> y_train, y_test = temporal_train_test_split(y)
  >>> transformer = Imputer(method="drift")
  >>> transformer.fit(y_train)
  Imputer(...)
  >>> y_test.iloc[3] = np.nan
  >>> y_hat = transformer.transform(y_test)
docstr: Transform X and return a transformed version.
  
  private _transform containing the core logic, called from transform
  
  Parameters
  ----------
  X : pd.Series or pd.DataFrame
      Data to be transformed
  y : ignored argument for interface compatibility
      Additional data, e.g., labels for transformation
  
  Returns
  -------
  X : pd.Series or pd.DataFrame, same type as X
      transformed version of X
docstr_tok: ["Transform","X","and","return","a","transformed","version",".","private","_transform","containing","the","core","logic",",","called","from","transform","Parameters","--","--","--","--","--","X",":","pd.Series","or","pd.DataFrame","Data","to","be","transformed","y",":","ignored","argument","for","interface","compatibility","Additional","data",",","e.g.",",","labels","for","transformation","Returns","--","--","--","-","X",":","pd.Series","or","pd.DataFrame",",","same","type","as","X","transformed","version","of","X"]
code: def _transform(self, X, y=None):
      """Transform X and return a transformed version.
  
      private _transform containing the core logic, called from transform
  
      Parameters
      ----------
      X : pd.Series or pd.DataFrame
          Data to be transformed
      y : ignored argument for interface compatibility
          Additional data, e.g., labels for transformation
  
      Returns
      -------
      X : pd.Series or pd.DataFrame, same type as X
          transformed version of X
      """
      X = X.copy()
  
      # replace missing_values with np.nan
      if self.missing_values:
          X = X.replace(to_replace=self.missing_values, value=np.nan)
  
      if not _has_missing_values(X):
          return X
  
      index = X.index
  
      if self.method == "random":
          for col in X.columns:
              isna = X[col].isna()
              X.loc[isna, col] = self._create_random_distribution(
                  X[col]
              )(isna.sum())
          return X
      elif self.method == "constant":
          return X.fillna(value=self.value)
      elif isinstance(index, pd.MultiIndex):
          X_grouped = X.groupby(level=list(range(index.nlevels - 1)))
  
          if self.method in ["backfill", "bfill"]:
              X = X_grouped.bfill()
              # fill trailing NAs of panel instances with reverse method
              return X.ffill()
          elif self.method in ["pad", "ffill"]:
              X = X_grouped.ffill()
              # fill leading NAs of panel instances with reverse method
              return X.bfill()
          elif self.method == "mean":
              return X_grouped.fillna(value=self._mean)
          elif self.method == "median":
              return X_grouped.fillna(value=self._median)
          else:
              raise AssertionError("Code should not be reached")
      else:
          if self.method in ["backfill", "bfill"]:
              X = X.bfill()
          elif self.method in ["pad", "ffill"]:
              X = X.ffill()
          elif self.method == "drift":
              X = self._impute_with_forecaster(X, y)
          elif self.method == "forecaster":
              X = self._impute_with_forecaster(X, y)
          elif self.method == "mean":
              return X.fillna(value=self._mean)
          elif self.method == "median":
              return X.fillna(value=self._median)
          elif self.method in ["nearest", "linear"]:
              X = X.interpolate(method=self.method)
          else:
              raise ValueError(
                  f"`method`: {self.method} not available."
              )
  
          # fill first/last elements of series,
          # as some methods (e.g. "linear") can't impute those
          X = X.ffill().bfill()
  
          return X
  
file_path: sktime/sktime/transformations/series/impute.py
imports: import numpy
  import pandas
  from sklearn.utils import check_random_state
  from sktime.forecasting.base import ForecastingHorizon
  from sktime.forecasting.trend import PolynomialTrendForecaster
  from sktime.transformations.base import BaseTransformer
label_desc: Use image node_id 3 for calling the Imputer obj's underlying member method code with example usage: obj._transform(X, y) and returns: X, X, X, X, X, X, X_grouped, X_grouped, X, X