def stack_samples(vals: Union[np.ndarray, TimeSeries]) -> np.ndarray:
        """
        Creates an array of shape `(n_timesteps * n_samples, n_components)` from
        either a `TimeSeries` or the `array_values` of a `TimeSeries`.

        Each column of the returned array corresponds to a component (dimension)
        of the series and is formed by concatenating all of the samples associated
        with that component together. More specifically, the `i`th column is formed
        by concatenating
        `[component_i_sample_1, component_i_sample_2, ..., component_i_sample_n]`.

        Stacking is useful when implementing a transformation that applies the exact same
        change to every timestep in the timeseries. In such cases, the samples of each
        component can be stacked together into a single column, and the transformation can then be
        applied to each column, thereby 'vectorising' the transformation over all samples of that component;
        the `unstack_samples` method can then be used to reshape the output. For transformations that depend
        on the `time_index` or the temporal ordering of the observations, stacking should *not* be employed.

        Parameters
        ----------
        vals
            `Timeseries` or `np.ndarray` of shape `(n_timesteps, n_components, n_samples)` to be 'stacked'.

        Returns
        -------
        stacked
            `np.ndarray` of shape `(n_timesteps * n_samples, n_components)`, where the `i`th column is formed
            by concatenating all of the samples of the `i`th component in `vals`.
        """
        if isinstance(vals, TimeSeries):
            vals = vals.all_values()
        shape = vals.shape
        new_shape = (shape[0] * shape[2], shape[1])
        stacked = np.swapaxes(vals, 1, 2).reshape(new_shape)
        return stacked

        Creates an array of shape `(n_timesteps * n_samples, n_components)` from
        either a `TimeSeries` or the `array_values` of a `TimeSeries`.

        Each column of the returned array corresponds to a component (dimension)
        of the series and is formed by concatenating all of the samples associated
        with that component together. More specifically, the `i`th column is formed
        by concatenating
        `[component_i_sample_1, component_i_sample_2, ..., component_i_sample_n]`.

        Stacking is useful when implementing a transformation that applies the exact same
        change to every timestep in the timeseries. In such cases, the samples of each
        component can be stacked together into a single column, and the transformation can then be
        applied to each column, thereby 'vectorising' the transformation over all samples of that component;
        the `unstack_samples` method can then be used to reshape the output. For transformations that depend
        on the `time_index` or the temporal ordering of the observations, stacking should *not* be employed.

        Parameters
        ----------
        vals
            `Timeseries` or `np.ndarray` of shape `(n_timesteps, n_components, n_samples)` to be 'stacked'.

        Returns
        -------
        stacked
            `np.ndarray` of shape `(n_timesteps * n_samples, n_components)`, where the `i`th column is formed
            by concatenating all of the samples of the `i`th component in `vals`.
        
darts/dataprocessing/transformers/base_data_transformer.py