Skip to content

median_crossing_rate

timecave.data_characteristics.median_crossing_rate(ts)

Compute the series' median-crossing rate.

This function computes the median-crossing rate of a given time series. The median-crossing rate is defined as the rate at which the values of a time series change from being below its median value to above said value. In practice, the median is subtracted from the time series, and the zero-crossing rate is then computed.

Parameters:

Name Type Description Default
ts ndarray | Series

Univariate time series.

required

Returns:

Type Description
float

Median-crossing rate.

Raises:

Type Description
TypeError

If ts is neither a Numpy array nor a Pandas series.

See also

mean_crossing_rate Uses the mean instead of the median.

Notes

The median-crossing rate is similar to the mean-crossing rate, but it uses the median as a reference value. It can be computed from the following formula:

\[ MedCR = \frac{1}{n-1} \sum_{i=2}^{n} |sign(a_i - Med) - sign(a_{i-1} - Med)| \]

where \(n\) is the number of samples in the time series, \(a_i\) are its values, and \(Med\) represents its median. The formula for the mean-crossing rate can be found in [1].

References

1

Bohdan Myroniv, Cheng-Wei Wu, Yi Ren, Albert Christian, Ensa Bajo, and Yu-chee Tseng. Analyzing user emotions via physiology signals. Data Science and Pattern Recognition, 2, 12 2017.

Examples:

>>> import numpy as np
>>> from timecave.data_characteristics import median_crossing_rate
>>> ts = np.array([0, 20, 0, 20, 0]);
>>> median_crossing_rate(ts)
1.0
>>> ts2 = np.ones(10);
>>> median_crossing_rate(ts2)
0.0
>>> ts3 = np.array([50, 50, 50, 0, 0]);
>>> median_crossing_rate(ts3)
0.25
>>> ts4 = np.array([0, 20, 5, 5, 5]);
>>> median_crossing_rate(ts4)
0.5

If the time series is neither an array nor a series, an exception is thrown:

>>> median_crossing_rate([0, 1, 2])
Traceback (most recent call last):
...
TypeError: Time series must be either a Numpy array or a Pandas series.
Source code in timecave/data_characteristics.py
def median_crossing_rate(ts: np.ndarray | pd.Series) -> float:

    """
    Compute the series' median-crossing rate.

    This function computes the median-crossing rate of a given time series.
    The median-crossing rate is defined as the rate at which the values of a time
    series change from being below its median value to above said value.
    In practice, the median is subtracted from the time series, and the zero-crossing
    rate is then computed.

    Parameters
    ----------
    ts : np.ndarray | pd.Series
        Univariate time series.

    Returns
    -------
    float
        Median-crossing rate.

    Raises
    ------
    TypeError
        If `ts` is neither a Numpy array nor a Pandas series.

    See also
    --------
    [mean_crossing_rate](mean_cr.md)
        Uses the mean instead of the median.

    Notes
    -----
    The median-crossing rate is similar to the mean-crossing rate, but it uses the median as a reference value. \
    It can be computed from the following formula:

    $$
    MedCR = \\frac{1}{n-1} \sum_{i=2}^{n} |sign(a_i - Med) - sign(a_{i-1} - Med)|  
    $$

    where $n$ is the number of samples in the time series, $a_i$ are its values, and $Med$ represents its median.
    The formula for the mean-crossing rate can be found in [[1]](#1).

    References
    ----------
    ##1
    Bohdan Myroniv, Cheng-Wei Wu, Yi Ren, Albert Christian, Ensa Bajo,
    and Yu-chee Tseng. Analyzing user emotions via physiology signals. Data
    Science and Pattern Recognition, 2, 12 2017.

    Examples
    --------
    >>> import numpy as np
    >>> from timecave.data_characteristics import median_crossing_rate
    >>> ts = np.array([0, 20, 0, 20, 0]);
    >>> median_crossing_rate(ts)
    1.0
    >>> ts2 = np.ones(10);
    >>> median_crossing_rate(ts2)
    0.0
    >>> ts3 = np.array([50, 50, 50, 0, 0]);
    >>> median_crossing_rate(ts3)
    0.25
    >>> ts4 = np.array([0, 20, 5, 5, 5]);
    >>> median_crossing_rate(ts4)
    0.5

    If the time series is neither an array nor a series, an exception is thrown:

    >>> median_crossing_rate([0, 1, 2])
    Traceback (most recent call last):
    ...
    TypeError: Time series must be either a Numpy array or a Pandas series.
    """

    _check_type(ts);

    if(isinstance(ts, pd.Series) is True):

        ts = ts.to_numpy();

    new_ts = ts - np.median(ts);

    mcr = np.nonzero(np.diff(np.sign(new_ts)))[0].shape[0] / (ts.shape[0] - 1);

    return mcr;