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

1# ============================================================================ # 

2# # 

3# Title: Stability Tests # 

4# Purpose: Convenience functions for stability algorithms. # 

5# # 

6# ============================================================================ # 

7 

8 

9# ---------------------------------------------------------------------------- # 

10# # 

11# Overview #### 

12# # 

13# ---------------------------------------------------------------------------- # 

14 

15 

16# ---------------------------------------------------------------------------- # 

17# Description #### 

18# ---------------------------------------------------------------------------- # 

19 

20 

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""" 

25 

26 

27# ---------------------------------------------------------------------------- # 

28# # 

29# Setup #### 

30# # 

31# ---------------------------------------------------------------------------- # 

32 

33 

34# ---------------------------------------------------------------------------- # 

35# Imports #### 

36# ---------------------------------------------------------------------------- # 

37 

38 

39# ## Python StdLib Imports ---- 

40from typing import Union 

41 

42# ## Python Third Party Imports ---- 

43import numpy as np 

44import pandas as pd 

45from numpy.typing import NDArray 

46from typeguard import typechecked 

47 

48# ## Local First Party Imports ---- 

49from ts_stat_tests.stability.algorithms import ( 

50 lumpiness as _lumpiness, 

51 stability as _stability, 

52) 

53 

54 

55# ---------------------------------------------------------------------------- # 

56# Exports #### 

57# ---------------------------------------------------------------------------- # 

58 

59 

60__all__: list[str] = ["is_stable", "is_lumpy"] 

61 

62 

63# ---------------------------------------------------------------------------- # 

64# # 

65# Algorithms #### 

66# # 

67# ---------------------------------------------------------------------------- # 

68 

69 

70# -----------------------------------------------------------------------------# 

71# Stability #### 

72# -----------------------------------------------------------------------------# 

73 

74 

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. 

84 

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). 

87 

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` 

97 

98 Returns: 

99 (bool): 

100 `True` if the stability metric is less than `alpha` (the series is stable), otherwise `False`. 

101 

102 ???+ example "Examples" 

103 

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 

108 

109 ``` 

110 

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 

115 

116 ``` 

117 

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 

123 

124 ``` 

125 

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 

130 

131 

132# ------------------------------------------------------------------------------# 

133# Lumpiness #### 

134# ------------------------------------------------------------------------------# 

135 

136 

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. 

146 

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. 

149 

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` 

159 

160 Returns: 

161 (bool): 

162 `True` if the lumpiness metric is greater than `alpha` (the series is lumpy), otherwise `False`. 

163 

164 ???+ example "Examples" 

165 

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 

170 

171 ``` 

172 

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 

177 

178 ``` 

179 

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 

185 

186 ``` 

187 

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