def METHOD_NAME(self, X, y=None):
    """Transform X and return a transformed version.
    private _transform containing core logic, called from transform
    Parameters
    ----------
    X : Series or Panel of mtype X_inner_mtype
        if X_inner_mtype is list, _transform must support all types in it
        Data to be transformed
    y : Series or Panel of mtype y_inner_mtype, default=None
        Additional data, e.g., labels for transformation
    Returns
    -------
    transformed version of X
    """
    bins = self.bins
    idx_cut = pd.cut(X.index, bins=self._bins, include_lowest=True)
    Xt = X.groupby(idx_cut).apply(self._aggfunc)
    if self.return_index == "range":
        Xt = Xt.reset_index(drop=True)
    elif self.return_index == "bin_start":
        if bins is pd.IntervalIndex:
            Xt.index = [x.left for x in Xt.index]
        else:
            Xt.index = bins[:-1]
    elif self.return_index == "bin_end":
        if bins is pd.IntervalIndex:
            Xt.index = [x.right for x in Xt.index]
        else:
            Xt.index = bins[1:]
    elif self.return_index == "bin_mid":
        if bins is pd.IntervalIndex:
            Xt.index = [(x.left + x.right) / 2 for x in Xt.index]
        else:
            Xt.index = [(bins[i] + bins[i + 1]) / 2 for i in range(len(bins))]
    elif self.return_index == "bin":
        Xt.index = self._bins
    return Xt