class_docstr: Transformer for multivariate time series.
  
  It provides a convenient class to transform multivariate time series with
  transformers that can only deal with univariate time series.
  
  Parameters
  ----------
  estimator : estimator object or list thereof
      Transformer. If one estimator is provided, it is cloned and each clone
      transforms one feature. If a list of estimators is provided, each
      estimator transforms one feature.
  
  flatten : bool (default = True)
      Affect shape of transform output. If True, ``transform``
      returns an array with shape (n_samples, \*). If False, the output of
      ``transform`` from each estimator must have the same shape and
      ``transform`` returns an array with shape (n_samples, n_features, \*).
      Ignored if the transformers return sparse matrices.
  
  Attributes
  ----------
  estimators_ : list of estimator objects
      The collection of fitted transformers.
  
  Examples
  --------
  >>> from pyts.datasets import load_basic_motions
  >>> from pyts.multivariate.transformation import MultivariateTransformer
  >>> from pyts.image import GramianAngularField
  >>> X, _, _, _ = load_basic_motions(return_X_y=True)
  >>> transformer = MultivariateTransformer(GramianAngularField(),
  ...                                       flatten=False)
  >>> X_new = transformer.fit_transform(X)
  >>> X_new.shape
  (40, 6, 100, 100)
docstr: Apply transform to each feature.
  
  Parameters
  ----------
  X : array-like, shape = (n_samples, n_features, n_timestamps)
      Multivariate time series.
  
  Returns
  -------
  X_new : array, shape = (n_samples, *) or (n_samples, n_features, *)
      Transformed time series.
docstr_tok: ["Apply","transform","to","each","feature",".","Parameters","--","--","--","--","--","X",":","array-like",",","shape","=","(","n_samples",",","n_features",",","n_timestamps",")","Multivariate","time","series",".","Returns","--","--","--","-","X_new",":","array",",","shape","=","(","n_samples",",","*",")","or","(","n_samples",",","n_features",",","*",")","Transformed","time","series","."]
code: def transform(self, X):
      r"""Apply transform to each feature.
  
      Parameters
      ----------
      X : array-like, shape = (n_samples, n_features, n_timestamps)
          Multivariate time series.
  
      Returns
      -------
      X_new : array, shape = (n_samples, *) or (n_samples, n_features, *)
          Transformed time series.
  
      """
      X = check_3d_array(X)
      n_samples, _, _ = X.shape
      check_is_fitted(self, "estimators_")
  
      X_transformed = [
          transformer.transform(X[:, i, :])
          for i, transformer in enumerate(self.estimators_)
      ]
      all_sparse = np.all(
          [
              isinstance(X_transformed_i, csr_matrix)
              for X_transformed_i in X_transformed
          ]
      )
      if all_sparse:
          X_new = hstack(X_transformed)
      else:
          X_new = [
              self._convert_to_array(X_transformed_i)
              for X_transformed_i in X_transformed
          ]
          ndims = [X_new_i.ndim for X_new_i in X_new]
          shapes = [X_new_i.shape for X_new_i in X_new]
          one_dim = np.unique(ndims).size == 1
          if one_dim:
              one_shape = np.unique(shapes, axis=0).shape[0] == 1
          else:
              one_shape = False
          if (not one_shape) or self.flatten:
              X_new = [
                  X_new_i.reshape(n_samples, -1) for X_new_i in X_new
              ]
              X_new = np.concatenate(X_new, axis=1)
          else:
              X_new = np.asarray(X_new)
              axes = [1, 0] + [i for i in range(2, X_new.ndim)]
              X_new = np.transpose(X_new, axes=axes)
      return X_new
  
file_path: pyts/pyts/multivariate/transformation/multivariate.py
imports: import numpy
  from scipy.sparse import csr_matrix, hstack
  from sklearn.base import BaseEstimator, clone
  from sklearn.utils.validation import check_is_fitted
  from ...base import MultivariateTransformerMixin
  from ..utils import check_3d_array
label_desc: Use image node_id 3 for calling the MultivariateTransformer obj's underlying member method code with example usage: obj.transform(X) and returns: X_new