dycw-utilities 0.109.19__py3-none-any.whl → 0.109.21__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.109.19
3
+ Version: 0.109.21
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=NU7I4AynUyg4F6Vu4XytgM7aO4TDKxvPbBFKo638x30,61
1
+ utilities/__init__.py,sha256=Q2YV4YDdpMRcnIlWhuT_v301enhQDMFopz9BOGv-13g,61
2
2
  utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
3
3
  utilities/astor.py,sha256=xuDUkjq0-b6fhtwjhbnebzbqQZAjMSHR1IIS5uOodVg,777
4
4
  utilities/asyncio.py,sha256=41oQUurWMvadFK5gFnaG21hMM0Vmfn2WS6OpC0R9mas,14757
@@ -28,7 +28,7 @@ utilities/hypothesis.py,sha256=sLqYcrFn0I3o0R7maqliIERRtAcREk2CKG8rSHY1t5U,46205
28
28
  utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
29
29
  utilities/iterables.py,sha256=2Yy9gZ7BR4LXR4nlX7outFAjd4dpb3lgUo7ji_sdylY,45076
30
30
  utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
31
- utilities/lightweight_charts.py,sha256=0xNfcsrgFI0R9xL25LtSm-W5yhfBI93qQNT6HyaXAhg,2769
31
+ utilities/lightweight_charts.py,sha256=vyVOzarYhBIOZj2xDhqdbP85qbSKUjdc6Au91rc1W4M,2814
32
32
  utilities/logging.py,sha256=opIwFjGKOYyMntVeCsFNXOmTY2z02hMf2UtCB76SaI4,25142
33
33
  utilities/loguru.py,sha256=MEMQVWrdECxk1e3FxGzmOf21vWT9j8CAir98SEXFKPA,3809
34
34
  utilities/luigi.py,sha256=fpH9MbxJDuo6-k9iCXRayFRtiVbUtibCJKugf7ygpv0,5988
@@ -46,7 +46,7 @@ utilities/pathlib.py,sha256=31WPMXdLIyXgYOMMl_HOI2wlo66MGSE-cgeelk-Lias,1410
46
46
  utilities/period.py,sha256=ikHXsWtDLr553cfH6p9mMaiCnIAP69B7q84ckWV3HaA,10884
47
47
  utilities/pickle.py,sha256=Bhvd7cZl-zQKQDFjUerqGuSKlHvnW1K2QXeU5UZibtg,657
48
48
  utilities/platform.py,sha256=NU7ycTvAXAG-fdYmDXaM1m4EOml2cGiaYwaUzfzSqyU,1767
49
- utilities/polars.py,sha256=UFrD7smyBROlIBaLD6tUFKGAPtwLfyHPHp6dJI9i-kQ,54961
49
+ utilities/polars.py,sha256=27oT-CmOtlAEdsZ2XOoN1GLINnRM2Byj_oBtsHGmp3c,57444
50
50
  utilities/polars_ols.py,sha256=efhXf0gjrHUpQrvS6a7g8yJQJWf_ATKtJnqqF2inCOU,5680
51
51
  utilities/pqdm.py,sha256=foRytQybmOQ05pjt5LF7ANyzrIa--4ScDE3T2wd31a4,3118
52
52
  utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -68,6 +68,7 @@ utilities/slack_sdk.py,sha256=SeDNMh24IPiEBWoGMdgvrflUaFa9TGlTS03H9-NKaQw,4132
68
68
  utilities/socket.py,sha256=K77vfREvzoVTrpYKo6MZakol0EYu2q1sWJnnZqL0So0,118
69
69
  utilities/sqlalchemy.py,sha256=GWzp54TP3F2mGhxPTn0c56KxxDeN9VKLMagcRSELhf4,35453
70
70
  utilities/sqlalchemy_polars.py,sha256=oGyMX5gSxuLI3N8mtz_-ml3UdWKcZuj6aFRW6ifI0Kc,15617
71
+ utilities/statsmodels.py,sha256=F0bNmPUCmi3GsfpSuTVBYWxGimKury-pmcpFQ-SJ65I,2629
71
72
  utilities/streamlit.py,sha256=U9PJBaKP1IdSykKhPZhIzSPTZsmLsnwbEPZWzNhJPKk,2955
72
73
  utilities/sys.py,sha256=h0Xr7Vj86wNalvwJVP1wj5Y0kD_VWm1vzuXZ_jw94mE,2743
73
74
  utilities/tempfile.py,sha256=VqmZJAhTJ1OaVywFzk5eqROV8iJbW9XQ_QYAV0bpdRo,1384
@@ -86,7 +87,7 @@ utilities/warnings.py,sha256=yUgjnmkCRf6QhdyAXzl7u0qQFejhQG3PrjoSwxpbHrs,1819
86
87
  utilities/whenever.py,sha256=TjoTAJ1R27-rKXiXzdE4GzPidmYqm0W58XydDXp-QZM,17786
87
88
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
88
89
  utilities/zoneinfo.py,sha256=-DQz5a0Ikw9jfSZtL0BEQkXOMC9yGn_xiJYNCLMiqEc,1989
89
- dycw_utilities-0.109.19.dist-info/METADATA,sha256=nYNr6kZIYFI-2yrn7iwBAs_Axo9Zqi5-bKBZpNBc1Q0,13005
90
- dycw_utilities-0.109.19.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
91
- dycw_utilities-0.109.19.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
92
- dycw_utilities-0.109.19.dist-info/RECORD,,
90
+ dycw_utilities-0.109.21.dist-info/METADATA,sha256=oeS1xA25IzXCADvmuZu2P1ULQ3p1Kyv0_tkEcZmZzDo,13005
91
+ dycw_utilities-0.109.21.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ dycw_utilities-0.109.21.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
93
+ dycw_utilities-0.109.21.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.109.19"
3
+ __version__ = "0.109.21"
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
13
13
  from lightweight_charts import AbstractChart, Chart
14
14
  from lightweight_charts.abstract import SeriesCommon
15
15
  from polars import DataFrame
16
- from polars._typing import SchemaDict
16
+ from polars._typing import SchemaDict # pyright: ignore[reportPrivateImportUsage]
17
17
 
18
18
  from utilities.types import PathLike
19
19
 
utilities/polars.py CHANGED
@@ -121,6 +121,7 @@ if TYPE_CHECKING:
121
121
  )
122
122
 
123
123
  from utilities.numpy import NDArrayB, NDArrayF
124
+ from utilities.statsmodels import ACFMissing
124
125
  from utilities.types import (
125
126
  Dataclass,
126
127
  MaybeIterable,
@@ -143,6 +144,85 @@ _FINITE_EWM_MIN_WEIGHT = 0.9999
143
144
  ##
144
145
 
145
146
 
147
+ def acf(
148
+ series: Series,
149
+ /,
150
+ *,
151
+ adjusted: bool = False,
152
+ nlags: int | None = None,
153
+ qstat: bool = False,
154
+ fft: bool = True,
155
+ alpha: float | None = None,
156
+ bartlett_confint: bool = True,
157
+ missing: ACFMissing = "none",
158
+ ) -> DataFrame:
159
+ """Compute the autocorrelations of a series."""
160
+ from numpy import ndarray
161
+
162
+ import utilities.statsmodels
163
+
164
+ array = series.to_numpy()
165
+ result = utilities.statsmodels.acf(
166
+ array,
167
+ adjusted=adjusted,
168
+ nlags=nlags,
169
+ qstat=qstat,
170
+ fft=fft,
171
+ alpha=alpha,
172
+ bartlett_confint=bartlett_confint,
173
+ missing=missing,
174
+ )
175
+ match result:
176
+ case ndarray() as acfs:
177
+ return _acf_process_acfs(acfs)
178
+ case ndarray() as acfs, ndarray() as confints:
179
+ df_acfs = _acf_process_acfs(acfs)
180
+ df_confints = _acf_process_confints(confints)
181
+ return df_acfs.join(df_confints, on=["lag"])
182
+ case ndarray() as acfs, ndarray() as qstats, ndarray() as pvalues:
183
+ df_acfs = _acf_process_acfs(acfs)
184
+ df_qstats_pvalues = _acf_process_qstats_pvalues(qstats, pvalues)
185
+ return df_acfs.join(df_qstats_pvalues, on=["lag"], how="left")
186
+ case (
187
+ ndarray() as acfs,
188
+ ndarray() as confints,
189
+ ndarray() as qstats,
190
+ ndarray() as pvalues,
191
+ ):
192
+ df_acfs = _acf_process_acfs(acfs)
193
+ df_confints = _acf_process_confints(confints)
194
+ df_qstats_pvalues = _acf_process_qstats_pvalues(qstats, pvalues)
195
+ return join(df_acfs, df_confints, df_qstats_pvalues, on=["lag"], how="left")
196
+ case _ as never:
197
+ assert_never(never)
198
+
199
+
200
+ def _acf_process_acfs(acfs: NDArrayF, /) -> DataFrame:
201
+ return (
202
+ Series(name="autocorrelation", values=acfs, dtype=Float64)
203
+ .to_frame()
204
+ .with_row_index(name="lag")
205
+ )
206
+
207
+
208
+ def _acf_process_confints(confints: NDArrayF, /) -> DataFrame:
209
+ return DataFrame(
210
+ data=confints, schema={"lower": Float64, "upper": Float64}
211
+ ).with_row_index(name="lag")
212
+
213
+
214
+ def _acf_process_qstats_pvalues(qstats: NDArrayF, pvalues: NDArrayF, /) -> DataFrame:
215
+ from numpy import hstack
216
+
217
+ data = hstack([qstats.reshape(-1, 1), pvalues.reshape(-1, 1)])
218
+ return DataFrame(
219
+ data=data, schema={"qstat": Float64, "pvalue": Float64}
220
+ ).with_row_index(name="lag", offset=1)
221
+
222
+
223
+ ##
224
+
225
+
146
226
  def adjust_frequencies(
147
227
  series: Series,
148
228
  /,
@@ -1840,6 +1920,7 @@ __all__ = [
1840
1920
  "SetFirstRowAsColumnsError",
1841
1921
  "StructFromDataClassError",
1842
1922
  "YieldStructSeriesElementsError",
1923
+ "acf",
1843
1924
  "adjust_frequencies",
1844
1925
  "append_dataclass",
1845
1926
  "are_frames_equal",
@@ -0,0 +1,117 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any, Literal, cast, overload
4
+
5
+ import statsmodels.tsa.stattools
6
+
7
+ if TYPE_CHECKING:
8
+ from utilities.numpy import NDArrayF
9
+
10
+
11
+ type ACFMissing = Literal["none", "raise", "conservative", "drop"]
12
+
13
+
14
+ @overload
15
+ def acf(
16
+ array: NDArrayF,
17
+ /,
18
+ *,
19
+ adjusted: bool = False,
20
+ nlags: int | None = None,
21
+ qstat: Literal[False] = False,
22
+ fft: bool = True,
23
+ alpha: None = None,
24
+ bartlett_confint: bool = True,
25
+ missing: ACFMissing = "none",
26
+ ) -> NDArrayF: ...
27
+ @overload
28
+ def acf(
29
+ array: NDArrayF,
30
+ /,
31
+ *,
32
+ adjusted: bool = False,
33
+ nlags: int | None = None,
34
+ qstat: Literal[False] = False,
35
+ fft: bool = True,
36
+ alpha: float,
37
+ bartlett_confint: bool = True,
38
+ missing: ACFMissing = "none",
39
+ ) -> tuple[NDArrayF, NDArrayF]: ...
40
+ @overload
41
+ def acf(
42
+ array: NDArrayF,
43
+ /,
44
+ *,
45
+ adjusted: bool = False,
46
+ nlags: int | None = None,
47
+ qstat: Literal[True],
48
+ fft: bool = True,
49
+ alpha: float,
50
+ bartlett_confint: bool = True,
51
+ missing: ACFMissing = "none",
52
+ ) -> tuple[NDArrayF, NDArrayF, NDArrayF, NDArrayF]: ...
53
+ @overload
54
+ def acf(
55
+ array: NDArrayF,
56
+ /,
57
+ *,
58
+ adjusted: bool = False,
59
+ nlags: int | None = None,
60
+ qstat: Literal[True],
61
+ fft: bool = True,
62
+ alpha: None = None,
63
+ bartlett_confint: bool = True,
64
+ missing: ACFMissing = "none",
65
+ ) -> tuple[NDArrayF, NDArrayF, NDArrayF]: ...
66
+ @overload
67
+ def acf(
68
+ array: NDArrayF,
69
+ /,
70
+ *,
71
+ adjusted: bool = False,
72
+ nlags: int | None = None,
73
+ qstat: bool = False,
74
+ fft: bool = True,
75
+ alpha: float | None = None,
76
+ bartlett_confint: bool = True,
77
+ missing: ACFMissing = "none",
78
+ ) -> (
79
+ NDArrayF
80
+ | tuple[NDArrayF, NDArrayF]
81
+ | tuple[NDArrayF, NDArrayF, NDArrayF]
82
+ | tuple[NDArrayF, NDArrayF, NDArrayF, NDArrayF]
83
+ ): ...
84
+ def acf(
85
+ array: NDArrayF,
86
+ /,
87
+ *,
88
+ adjusted: bool = False,
89
+ nlags: int | None = None,
90
+ qstat: bool = False,
91
+ fft: bool = True,
92
+ alpha: float | None = None,
93
+ bartlett_confint: bool = True,
94
+ missing: ACFMissing = "none",
95
+ ) -> (
96
+ NDArrayF
97
+ | tuple[NDArrayF, NDArrayF]
98
+ | tuple[NDArrayF, NDArrayF, NDArrayF]
99
+ | tuple[NDArrayF, NDArrayF, NDArrayF, NDArrayF]
100
+ ):
101
+ """Typed version of `acf`."""
102
+ return cast(
103
+ "Any",
104
+ statsmodels.tsa.stattools.acf(
105
+ array,
106
+ adjusted=adjusted,
107
+ nlags=nlags,
108
+ qstat=qstat,
109
+ fft=fft,
110
+ alpha=alpha,
111
+ bartlett_confint=bartlett_confint,
112
+ missing=missing,
113
+ ),
114
+ )
115
+
116
+
117
+ __all__ = ["ACFMissing", "acf"]