Repository: sktime/sktime

Issue:
[ENH] Imputer for multivariate timeseries
**Is your feature request related to a problem? Please describe.**

Imputer Transformation (sktime.transformations.series.impute.Imputer) works only with univariate time series. So that one does not have to manipulate the data laboriously before, a multivariate version of Imputer would help. sktime.transformations.series.compose -> ColumnwiseTransformer could work with the Imputer. Is it planned to provide a multivariate imputer or should the ColumnwiseTransformer always be applied?

**Describe the solution you'd like**
A query of the dimension of the input data could be prefixed so that only one Imputer version is needed.

```
from sktime.transformations.base import _SeriesToSeriesTransformer
from sktime.transformations.series.compose import ColumnwiseTransformer
from sktime.transformations.series.impute import Imputer

__author__ = ["Martin Walter"]
__all__ = ["ImputerMultivariate"]

class ImputerMultivariate(_SeriesToSeriesTransformer):
    """Missing value imputation of multivariate timeseries.

        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 values.

            * "drift" : drift/trend values by sktime.PolynomialTrendForecaster()
            * "linear" : linear interpolation, by pd.Series.interpolate()
            * "nearest" : use nearest value, by pd.Series.interpolate()
            * "constant" : same constant value (given in arg value) for all NaN
            * "mean" : pd.Series.mean()
            * "median" : pd.Series.median()
            * "backfill" ot "bfill" : adapted from pd.Series.fillna()
            * "pad" or "ffill" : adapted from pd.Series.fillna()
            * "random" : random values between pd.Series.min() and .max()
            * "forecaster" : use an sktime Forecaster, given in arg forecaster

        missing_values : int/float/str, default=None
            The placeholder for the missing values. All occurrences of
            missing_values will be imputed. If None then np.nan is used.
        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.
        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
        >>> y = load_airline()
        >>> transformer = Imputer(method="drift")
        >>> y_hat = transformer.fit_transform(y)
    """
    _tags = {
            "fit-in-transform": True,
            "handles-missing-data": True,
            "skip-inverse-transform": True,
        }
    def __init__(
        self, 
        method="drift", 
        random_state=None, 
        value=None,
        forecaster=None,
        missing_values=None):

        self.transformer = ColumnwiseTransformer(
            Imputer(
            method=method,
            random_state=random_state,
            value=value,
            forecaster=forecaster,
            missing_values=missing_values,
        )
        )
        super(ImputerMultivariate, self).__init__()
    
    def fit(self, X, y=None):
        self._is_fitted = True
        self.transformer.fit(X, y)
        return self

    def transform(self, X, y=None):
        X = self.transformer.transform(X, y)
        return X
```



Discussion:

Resolving patch:
diff --git a/sktime/transformations/series/impute.py b/sktime/transformations/series/impute.py
--- a/sktime/transformations/series/impute.py
+++ b/sktime/transformations/series/impute.py
@@ -6,15 +6,17 @@
 __author__ = ["Martin Walter"]
 __all__ = ["Imputer"]
 
+
+import numpy as np
+import pandas as pd
+
+from sklearn.base import clone
+from sklearn.utils import check_random_state
+
 from sktime.transformations.base import _SeriesToSeriesTransformer
 from sktime.utils.validation.series import check_series
 from sktime.forecasting.trend import PolynomialTrendForecaster
-from sklearn.utils import check_random_state
 from sktime.forecasting.base import ForecastingHorizon
-from sklearn.base import clone
-
-import numpy as np
-import pandas as pd
 
 
 class Imputer(_SeriesToSeriesTransformer):
@@ -64,6 +66,7 @@ class Imputer(_SeriesToSeriesTransformer):
         "fit-in-transform": True,
         "handles-missing-data": True,
         "skip-inverse-transform": True,
+        "univariate-only": False,
     }
 
     def __init__(


Test patch: