class_docstr: Transformer that rolls two sliding windows side-by-side along a time
  series, aggregates using a user-given operation, and calcuates the
  difference of aggregated metrics between two sliding windows.
  
  Parameters
  ----------
  window: int or str, or 2-tuple of int or str
      Size of the rolling time window.
  
      - If int, it is the number of time point in this time window.
      - If str, it must be able to be converted into a pandas Timedelta
        object.
      - If tuple, it defines the size of left and right window respectively.
  
  agg: str or function, or 2-tuple of str or function
      Aggregation method applied to series.
      If str, must be one of supported built-in methods:
  
      - 'mean': mean of all values in a rolling window.
      - 'median': median of all values in a rolling window.
      - 'sum': summation of all values in a rolling window.
      - 'min': minimum of all values in a rolling window.
      - 'max': maximum of all values in a rolling window.
      - 'std': sample standard deviation of all values in a rolling window.
      - 'var': sample variance of all values in a rolling window.
      - 'skew': skewness of all values in a rolling window.
      - 'kurt': kurtosis of all values in a rolling window.
      - 'count': number of non-nan values in a rolling window.
      - 'nnz': number of non-zero values in a rolling window.
      - 'nunique': number of unique values in a rolling window.
      - 'quantile': quantile of all values in a rolling window. Require
        percentile parameter `q` in in parameter `agg_params`, which is a
        float or a list of float between 0 and 1 inclusive.
      - 'iqr': interquartile range, i.e. difference between 75% and 25%
        quantiles.
      - 'idr': interdecile range, i.e. difference between 90% and 10%
        quantiles.
      - 'hist': histogram of all values in a rolling window. Require
        parameter `bins` in parameter `agg_params` to define the bins. `bins`
        is either a list of floats, b1, ..., bn, which defines n-1 bins
        [b1, b2), [b2, b3), ..., [b{n-2}, b{n-1}), [b{n-1}, bn], or an
        integer that defines the number of equal-width bins in the range of
        input series.
  
      If function, it should accept a rolling window in form of a pandas
      Series, and return either a scalar or a 1D numpy array. To specify
      names of outputs, specify a list of strings as a parameter `names` in
      parameter `agg_params`.
  
      If tuple, elements correspond left and right window respectively.
  
      Default: 'mean'
  
  agg_params: dict or 2-tuple of dict, optional
      Parameters of aggregation function. If tuple, elements correspond left
      and right window respectively. Default: None.
  
  center: bool, optional
      If True, the current point is the right edge of right window;
      Otherwise, it is the right edge of left window.
      Default: True.
  
  min_periods: int or 2-tuple of int, optional
      Minimum number of observations in window required to have a value. If
      tuple, elements correspond left and right window respectively. Default:
      None, i.e. all observations must have values.
  
  diff: str or function, optional
      Difference method applied between aggregated metrics from the two
      sliding windows.
      If str, choose from supported built-in methods:
  
      - 'diff': Difference between values of aggregated metric (right minus
        left). Only applicable if the aggregated metric is scalar.
      - 'rel_diff': Relative difference between values of aggregated metric
        (right minus left divided left). Only applicable if the aggregated
        metric is scalar.
      - 'abs_rel_diff': Absolute relative difference between values of
        aggregated metric (right minus left divided left). Only applicable if
        the aggregated metric is scalar.
      - 'l1': Absolute difference if aggregated metric is scalar, or sum of
        elementwise absolute difference if it is a vector.
      - 'l2': Square root of sum of elementwise squared difference.
  
      If function, it accepts two input arguments that are the two outputs of
      applying aggregation method to the two windows, and returns a float
      number measuring the difference.
  
      Default: 'l1'
code: def _predict_core(self, s: pd.Series) -> pd.Series:
      if not (
          s.index.is_monotonic_increasing
          or s.index.is_monotonic_decreasing
      ):
          raise ValueError(
              "Time series must have a monotonic time index. "
          )
  
      agg = self.agg
      agg_params = (
          self.agg_params if (self.agg_params is not None) else {}
      )
      window = self.window
      min_periods = self.min_periods
      center = self.center
      diff = self.diff
  
      if not isinstance(agg, tuple):
          agg = (agg, agg)
  
      if not isinstance(agg_params, tuple):
          agg_params = (agg_params, agg_params)
  
      if not isinstance(window, tuple):
          window = (window, window)
  
      if not isinstance(min_periods, tuple):
          min_periods = (min_periods, min_periods)
  
      if center:
          if isinstance(window[0], int):
              s_rolling_left = RollingAggregate(
                  agg=agg[0],
                  agg_params=agg_params[0],
                  window=window[0],
                  min_periods=min_periods[0],
                  center=False,
              ).transform(s.shift(1))
          else:
              ra = RollingAggregate(
                  agg=agg[0],
                  agg_params=agg_params[0],
                  window=window[0],
                  min_periods=min_periods[0],
                  center=False,
              )
              if parse(pd.__version__) < parse("0.25"):
                  raise PandasBugError()
              ra._closed = "left"
              s_rolling_left = ra.transform(s)
          if isinstance(window[1], int):
              s_rolling_right = (
                  RollingAggregate(
                      agg=agg[1],
                      agg_params=agg_params[1],
                      window=window[1],
                      min_periods=min_periods[1],
                      center=False,
                  )
                  .transform(s.iloc[::-1])
                  .iloc[::-1]
              )
          else:
              s_reversed = pd.Series(
                  s.values[::-1],
                  index=pd.DatetimeIndex(
                      [
                          s.index[0] + (s.index[-1] - s.index[i])
                          for i in range(len(s) - 1, -1, -1)
                      ]
                  ),
              )
              s_rolling_right = pd.Series(
                  RollingAggregate(
                      agg=agg[1],
                      agg_params=agg_params[1],
                      window=window[1],
                      min_periods=min_periods[1],
                      center=False,
                  )
                  .transform(s_reversed)
                  .iloc[::-1]
                  .values,
                  index=s.index,
              )
              s_rolling_right.name = s.name
      else:
          if isinstance(window[1], int):
              s_rolling_left = RollingAggregate(
                  agg=agg[0],
                  agg_params=agg_params[0],
                  window=window[0],
                  min_periods=min_periods[0],
                  center=False,
              ).transform(s.shift(window[1]))
          else:
              s_shifted = pd.Series(
                  s.values, s.index + pd.Timedelta(window[1])
              )
              s_shifted = s_shifted.append(
                  pd.Series(index=s.index, dtype="float64")
              )
              s_shifted = s_shifted.iloc[
                  s_shifted.index.duplicated() == False
              ]
              s_shifted = s_shifted.sort_index()
              s_shifted.name = s.name
              s_rolling_left = RollingAggregate(
                  agg=agg[0],
                  agg_params=agg_params[0],
                  window=window[0],
                  min_periods=min_periods[0],
                  center=False,
              ).transform(s_shifted)
              if isinstance(s_rolling_left, pd.Series):
                  s_rolling_left = s_rolling_left[s.index]
              else:
                  s_rolling_left = s_rolling_left.loc[s.index, :]
          s_rolling_right = RollingAggregate(
              agg=agg[1],
              agg_params=agg_params[1],
              window=window[1],
              min_periods=min_periods[1],
              center=False,
          ).transform(s)
  
      if isinstance(s_rolling_left, pd.Series):
          if diff in ["l1", "l2"]:
              return abs(s_rolling_right - s_rolling_left)
          if diff == "diff":
              return s_rolling_right - s_rolling_left
          if diff == "rel_diff":
              return (s_rolling_right - s_rolling_left) / s_rolling_left
          if diff == "abs_rel_diff":
              return (
                  abs(s_rolling_right - s_rolling_left) / s_rolling_left
              )
  
      if isinstance(s_rolling_left, pd.DataFrame):
          if diff == "l1":
              return abs(s_rolling_right - s_rolling_left).sum(
                  axis=1, skipna=False
              )
          if diff == "l2":
              return ((s_rolling_right - s_rolling_left) ** 2).sum(
                  axis=1, skipna=False
              ) ** 0.5
  
      if callable(diff):
          s_rolling = s.copy()
          for i in range(len(s_rolling)):
              s_rolling.iloc[i] = diff(
                  s_rolling_left.iloc[i], s_rolling_right.iloc[i]
              )
          return s_rolling
  
      raise ValueError("Invalid value of diff")
  
imports: from typing import Any, Callable, Dict, List, Optional, Tuple, Union
  import numpy
  import pandas
  import statsmodels
  from packaging.version import parse
  from statsmodels.tsa.seasonal import seasonal_decompose
  from statsmodels.tsa.stattools import acf
  from .._transformer_base import _NonTrainableUnivariateTransformer, _TrainableUnivariateTransformer
  from .._utils import PandasBugError
label_desc: Use image node_id 3 for calling the DoubleRollingAggregate obj's underlying member method code with example usage: obj._predict_core(s) and returns: s_rolling, abs, unknown, unknown, unknown, abs, unknown