Coverage for src / ts_stat_tests / stability / tests.py: 100%
13 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-01 09:48 +0000
« prev ^ index » next coverage.py v7.13.2, created at 2026-02-01 09:48 +0000
1# ============================================================================ #
2# #
3# Title: Stability Tests #
4# Purpose: Convenience functions for stability algorithms. #
5# #
6# ============================================================================ #
9# ---------------------------------------------------------------------------- #
10# #
11# Overview ####
12# #
13# ---------------------------------------------------------------------------- #
16# ---------------------------------------------------------------------------- #
17# Description ####
18# ---------------------------------------------------------------------------- #
21"""
22!!! note "Summary"
23 This module contains convenience functions and tests for stability measures, allowing for easy access to stability and lumpiness algorithms.
24"""
27# ---------------------------------------------------------------------------- #
28# #
29# Setup ####
30# #
31# ---------------------------------------------------------------------------- #
34# ---------------------------------------------------------------------------- #
35# Imports ####
36# ---------------------------------------------------------------------------- #
39# ## Python StdLib Imports ----
40from typing import Union
42# ## Python Third Party Imports ----
43import numpy as np
44import pandas as pd
45from numpy.typing import NDArray
46from typeguard import typechecked
48# ## Local First Party Imports ----
49from ts_stat_tests.stability.algorithms import (
50 lumpiness as _lumpiness,
51 stability as _stability,
52)
55# ---------------------------------------------------------------------------- #
56# Exports ####
57# ---------------------------------------------------------------------------- #
60__all__: list[str] = ["is_stable", "is_lumpy"]
63# ---------------------------------------------------------------------------- #
64# #
65# Algorithms ####
66# #
67# ---------------------------------------------------------------------------- #
70# -----------------------------------------------------------------------------#
71# Stability ####
72# -----------------------------------------------------------------------------#
75@typechecked
76def is_stable(
77 data: Union[NDArray[np.float64], pd.DataFrame, pd.Series],
78 freq: int = 1,
79 alpha: float = 0.5,
80) -> bool:
81 r"""
82 !!! note "Summary"
83 Determine if a time series is stable based on a variance threshold.
85 ???+ abstract "Details"
86 A time series is considered stable if the variance of its windowed means (the stability metric) is below a specified threshold (`alpha`). High stability values indicate that the mean level of the series changes significantly over time (e.g., due to trends or structural breaks).
88 Params:
89 data (Union[NDArray[np.float64], pd.DataFrame, pd.Series]):
90 The time series data to analyse.
91 freq (int):
92 The number of observations per seasonal period or the desired window size for tiling.
93 Default: `1`
94 alpha (float):
95 The threshold for stability. The series is considered stable if the calculated stability metric is less than this value.
96 Default: `0.5`
98 Returns:
99 (bool):
100 `True` if the stability metric is less than `alpha` (the series is stable), otherwise `False`.
102 ???+ example "Examples"
104 ```pycon {.py .python linenums="1" title="Setup"}
105 >>> import numpy as np
106 >>> from ts_stat_tests.stability.tests import is_stable
107 >>> from ts_stat_tests.utils.data import load_airline
109 ```
111 ```pycon {.py .python linenums="1" title="Example 1: Check if airline data is stable"}
112 >>> data = load_airline().values
113 >>> is_stable(data, freq=12, alpha=1.0)
114 False
116 ```
118 ```pycon {.py .python linenums="1" title="Example 2: Check if random noise is stable"}
119 >>> rng = np.random.RandomState(42)
120 >>> data_random = rng.normal(0, 1, 144)
121 >>> is_stable(data_random, freq=12, alpha=1.0)
122 True
124 ```
126 ??? tip "See Also"
127 - [`stability()`][ts_stat_tests.stability.algorithms.stability]
128 """
129 return True if _stability(data=data, freq=freq) < alpha else False
132# ------------------------------------------------------------------------------#
133# Lumpiness ####
134# ------------------------------------------------------------------------------#
137@typechecked
138def is_lumpy(
139 data: Union[NDArray[np.float64], pd.DataFrame, pd.Series],
140 freq: int = 1,
141 alpha: float = 0.5,
142) -> bool:
143 r"""
144 !!! note "Summary"
145 Determine if a time series is lumpy based on a variance threshold.
147 ???+ abstract "Details"
148 A time series is considered lumpy if the variance of its windowed variances (the lumpiness metric) exceeds a specified threshold (`alpha`). High lumpiness values indicate that the volatility of the series is inconsistently distributed across time.
150 Params:
151 data (Union[NDArray[np.float64], pd.DataFrame, pd.Series]):
152 The time series data to analyse.
153 freq (int):
154 The number of observations per seasonal period or the desired window size for tiling.
155 Default: `1`
156 alpha (float):
157 The threshold for lumpiness. The series is considered lumpy if the calculated lumpiness metric is greater than this value.
158 Default: `0.5`
160 Returns:
161 (bool):
162 `True` if the lumpiness metric is greater than `alpha` (the series is lumpy), otherwise `False`.
164 ???+ example "Examples"
166 ```pycon {.py .python linenums="1" title="Setup"}
167 >>> import numpy as np
168 >>> from ts_stat_tests.stability.tests import is_lumpy
169 >>> from ts_stat_tests.utils.data import load_airline
171 ```
173 ```pycon {.py .python linenums="1" title="Example 1: Check if airline data is lumpy"}
174 >>> data = load_airline().values
175 >>> is_lumpy(data, freq=12, alpha=1.0)
176 True
178 ```
180 ```pycon {.py .python linenums="1" title="Example 2: Check if random noise is lumpy"}
181 >>> rng = np.random.RandomState(42)
182 >>> data_random = rng.normal(0, 1, 144)
183 >>> is_lumpy(data_random, freq=12, alpha=1.0)
184 False
186 ```
188 ??? tip "See Also"
189 - [`lumpiness()`][ts_stat_tests.stability.algorithms.lumpiness]
190 """
191 return True if _lumpiness(data=data, freq=freq) > alpha else False