dycw-utilities 0.109.17__py3-none-any.whl → 0.109.19__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.
- {dycw_utilities-0.109.17.dist-info → dycw_utilities-0.109.19.dist-info}/METADATA +1 -1
- {dycw_utilities-0.109.17.dist-info → dycw_utilities-0.109.19.dist-info}/RECORD +8 -8
- utilities/__init__.py +1 -1
- utilities/numpy.py +44 -27
- utilities/polars.py +106 -0
- utilities/polars_ols.py +3 -1
- {dycw_utilities-0.109.17.dist-info → dycw_utilities-0.109.19.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.109.17.dist-info → dycw_utilities-0.109.19.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=NU7I4AynUyg4F6Vu4XytgM7aO4TDKxvPbBFKo638x30,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
|
@@ -36,7 +36,7 @@ utilities/math.py,sha256=TexfvLCI12d9Sw5_W4pKVBZ3nRr3zk2iPkcEU7xdEWU,26771
|
|
36
36
|
utilities/memory_profiler.py,sha256=tf2C51P2lCujPGvRt2Rfc7VEw5LDXmVPCG3z_AvBmbU,962
|
37
37
|
utilities/modules.py,sha256=SnhsRHRUS1po_acejrINauihGQpPvVsp8RDNCei1OLQ,3173
|
38
38
|
utilities/more_itertools.py,sha256=CPUxrMAcTwRxbzbhiqPKi3Xx9hxqI0t6gkWjutaibGk,5534
|
39
|
-
utilities/numpy.py,sha256=
|
39
|
+
utilities/numpy.py,sha256=cBgCBet8YfZP_rb4nkCJHZx9_03qPEinVENMk1dGVYQ,25683
|
40
40
|
utilities/operator.py,sha256=0M2yZJ0PODH47ogFEnkGMBe_cfxwZR02T_92LZVZvHo,3715
|
41
41
|
utilities/optuna.py,sha256=loyJGWTzljgdJaoLhP09PT8Jz6o_pwBOwehY33lHkhw,1923
|
42
42
|
utilities/orjson.py,sha256=Wj5pzG_VdgoAy14a7Luhem-BgYrRtRFvvl_POiszRd0,36930
|
@@ -46,8 +46,8 @@ 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=
|
50
|
-
utilities/polars_ols.py,sha256=
|
49
|
+
utilities/polars.py,sha256=UFrD7smyBROlIBaLD6tUFKGAPtwLfyHPHp6dJI9i-kQ,54961
|
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
|
53
53
|
utilities/pydantic.py,sha256=f6qtR5mO2YMuyvNmbaEj5YeD9eGA4YYfb7Bjzh9jUs0,1845
|
@@ -86,7 +86,7 @@ utilities/warnings.py,sha256=yUgjnmkCRf6QhdyAXzl7u0qQFejhQG3PrjoSwxpbHrs,1819
|
|
86
86
|
utilities/whenever.py,sha256=TjoTAJ1R27-rKXiXzdE4GzPidmYqm0W58XydDXp-QZM,17786
|
87
87
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
88
88
|
utilities/zoneinfo.py,sha256=-DQz5a0Ikw9jfSZtL0BEQkXOMC9yGn_xiJYNCLMiqEc,1989
|
89
|
-
dycw_utilities-0.109.
|
90
|
-
dycw_utilities-0.109.
|
91
|
-
dycw_utilities-0.109.
|
92
|
-
dycw_utilities-0.109.
|
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,,
|
utilities/__init__.py
CHANGED
utilities/numpy.py
CHANGED
@@ -16,11 +16,10 @@ from numpy import (
|
|
16
16
|
errstate,
|
17
17
|
exp,
|
18
18
|
flatnonzero,
|
19
|
-
float64,
|
20
19
|
floating,
|
21
20
|
full_like,
|
22
21
|
inf,
|
23
|
-
|
22
|
+
integer,
|
24
23
|
isclose,
|
25
24
|
isfinite,
|
26
25
|
isinf,
|
@@ -39,11 +38,13 @@ from numpy.linalg import det, eig
|
|
39
38
|
from numpy.random import default_rng
|
40
39
|
from numpy.typing import NDArray
|
41
40
|
|
42
|
-
from utilities.iterables import is_iterable_not_str
|
41
|
+
from utilities.iterables import always_iterable, is_iterable_not_str
|
43
42
|
|
44
43
|
if TYPE_CHECKING:
|
45
44
|
from collections.abc import Callable, Iterable
|
46
45
|
|
46
|
+
from utilities.types import MaybeIterable
|
47
|
+
|
47
48
|
|
48
49
|
##
|
49
50
|
|
@@ -89,8 +90,9 @@ timedelta64as = dtype("timedelta64[as]")
|
|
89
90
|
|
90
91
|
NDArrayA = NDArray[Any]
|
91
92
|
NDArrayB = NDArray[bool_]
|
92
|
-
|
93
|
-
|
93
|
+
NDArrayC128 = NDArray[complex128]
|
94
|
+
NDArrayF = NDArray[floating[Any]]
|
95
|
+
NDArrayI = NDArray[integer[Any]]
|
94
96
|
NDArrayO = NDArray[object_]
|
95
97
|
|
96
98
|
|
@@ -135,7 +137,7 @@ class AsIntError(Exception): ...
|
|
135
137
|
|
136
138
|
|
137
139
|
def boxcar(
|
138
|
-
array:
|
140
|
+
array: NDArrayF,
|
139
141
|
/,
|
140
142
|
*,
|
141
143
|
loc_low: float = -1.0,
|
@@ -144,7 +146,7 @@ def boxcar(
|
|
144
146
|
slope_high: float = 1.0,
|
145
147
|
rtol: float | None = None,
|
146
148
|
atol: float | None = None,
|
147
|
-
) ->
|
149
|
+
) -> NDArrayF:
|
148
150
|
"""Construct a boxcar function."""
|
149
151
|
if not is_at_most(loc_low, loc_high, rtol=rtol, atol=atol):
|
150
152
|
raise _BoxCarLocationsError(low=loc_low, high=loc_high)
|
@@ -224,28 +226,43 @@ def fillna(array: NDArrayF, /, *, value: float = 0.0) -> NDArrayF:
|
|
224
226
|
##
|
225
227
|
|
226
228
|
|
227
|
-
def
|
229
|
+
def adjust_frequencies(
|
228
230
|
array: NDArrayF,
|
229
231
|
/,
|
230
|
-
|
232
|
+
*,
|
233
|
+
filters: MaybeIterable[Callable[[NDArrayF], NDArrayB]] | None = None,
|
234
|
+
weights: MaybeIterable[Callable[[NDArrayF], NDArrayF]] | None = None,
|
231
235
|
d: int = 1,
|
232
236
|
) -> NDArrayF:
|
233
|
-
"""
|
237
|
+
"""Adjust an array via its FFT frequencies."""
|
234
238
|
(n,) = array.shape
|
235
|
-
|
239
|
+
amplitudes = fft(array)
|
236
240
|
freqs = fftfreq(n, d=d)
|
237
|
-
|
238
|
-
|
241
|
+
if filters is not None:
|
242
|
+
amplitudes = reduce(
|
243
|
+
partial(_adjust_frequencies_filter_one, freqs=freqs),
|
244
|
+
always_iterable(filters),
|
245
|
+
amplitudes,
|
246
|
+
)
|
247
|
+
if weights is not None:
|
248
|
+
amplitudes = reduce(
|
249
|
+
partial(_adjust_frequencies_weight_one, freqs=freqs),
|
250
|
+
always_iterable(weights),
|
251
|
+
amplitudes,
|
252
|
+
)
|
253
|
+
return ifft(amplitudes).real
|
254
|
+
|
255
|
+
|
256
|
+
def _adjust_frequencies_filter_one(
|
257
|
+
acc: NDArrayC128, el: Callable[[NDArrayF], NDArrayB], /, *, freqs: NDArrayF
|
258
|
+
) -> NDArrayC128:
|
259
|
+
return where(el(freqs), acc, 0.0)
|
239
260
|
|
240
261
|
|
241
|
-
def
|
242
|
-
acc:
|
243
|
-
|
244
|
-
|
245
|
-
*,
|
246
|
-
freqs: NDArray[floating[Any]],
|
247
|
-
) -> NDArray[complex128]:
|
248
|
-
return where(el(freqs), acc, 0.0)
|
262
|
+
def _adjust_frequencies_weight_one(
|
263
|
+
acc: NDArrayC128, el: Callable[[NDArrayF], NDArrayF], /, *, freqs: NDArrayF
|
264
|
+
) -> NDArrayC128:
|
265
|
+
return acc * el(freqs)
|
249
266
|
|
250
267
|
|
251
268
|
##
|
@@ -284,12 +301,12 @@ class FlatN0MultipleError(FlatN0Error):
|
|
284
301
|
##
|
285
302
|
|
286
303
|
|
287
|
-
def get_frequency_spectrum(array: NDArrayF, /, *, d: int = 1) ->
|
304
|
+
def get_frequency_spectrum(array: NDArrayF, /, *, d: int = 1) -> NDArrayF:
|
288
305
|
"""Get the frequency spectrum."""
|
289
306
|
(n,) = array.shape
|
290
|
-
|
307
|
+
amplitudes = fft(array)
|
291
308
|
freqs = fftfreq(n, d=d)
|
292
|
-
amplitudes = np.abs(
|
309
|
+
amplitudes = np.abs(amplitudes)
|
293
310
|
data = np.hstack([freqs.reshape(-1, 1), amplitudes.reshape(-1, 1)])
|
294
311
|
return data[argsort(data[:, 0])]
|
295
312
|
|
@@ -908,14 +925,14 @@ def shift_bool(
|
|
908
925
|
|
909
926
|
|
910
927
|
def sigmoid(
|
911
|
-
array:
|
928
|
+
array: NDArrayF,
|
912
929
|
/,
|
913
930
|
*,
|
914
931
|
loc: float = 0.0,
|
915
932
|
slope: float = 1.0,
|
916
933
|
rtol: float | None = None,
|
917
934
|
atol: float | None = None,
|
918
|
-
) ->
|
935
|
+
) -> NDArrayF:
|
919
936
|
"""Construct a sigmoid function."""
|
920
937
|
if is_zero(slope, rtol=rtol, atol=atol):
|
921
938
|
raise SigmoidError
|
@@ -965,6 +982,7 @@ __all__ = [
|
|
965
982
|
"NDArrayO",
|
966
983
|
"ShiftError",
|
967
984
|
"SigmoidError",
|
985
|
+
"adjust_frequencies",
|
968
986
|
"array_indexer",
|
969
987
|
"as_int",
|
970
988
|
"boxcar",
|
@@ -983,7 +1001,6 @@ __all__ = [
|
|
983
1001
|
"datetime64us",
|
984
1002
|
"discretize",
|
985
1003
|
"fillna",
|
986
|
-
"filter_frequencies",
|
987
1004
|
"flatn0",
|
988
1005
|
"get_frequency_spectrum",
|
989
1006
|
"has_dtype",
|
utilities/polars.py
CHANGED
@@ -115,10 +115,12 @@ if TYPE_CHECKING:
|
|
115
115
|
JoinStrategy, # pyright: ignore[reportPrivateImportUsage]
|
116
116
|
JoinValidation, # pyright: ignore[reportPrivateImportUsage]
|
117
117
|
PolarsDataType, # pyright: ignore[reportPrivateImportUsage]
|
118
|
+
RollingInterpolationMethod, # pyright: ignore[reportPrivateImportUsage]
|
118
119
|
SchemaDict, # pyright: ignore[reportPrivateImportUsage]
|
119
120
|
TimeUnit, # pyright: ignore[reportPrivateImportUsage]
|
120
121
|
)
|
121
122
|
|
123
|
+
from utilities.numpy import NDArrayB, NDArrayF
|
122
124
|
from utilities.types import (
|
123
125
|
Dataclass,
|
124
126
|
MaybeIterable,
|
@@ -141,6 +143,27 @@ _FINITE_EWM_MIN_WEIGHT = 0.9999
|
|
141
143
|
##
|
142
144
|
|
143
145
|
|
146
|
+
def adjust_frequencies(
|
147
|
+
series: Series,
|
148
|
+
/,
|
149
|
+
*,
|
150
|
+
filters: MaybeIterable[Callable[[NDArrayF], NDArrayB]] | None = None,
|
151
|
+
weights: MaybeIterable[Callable[[NDArrayF], NDArrayF]] | None = None,
|
152
|
+
d: int = 1,
|
153
|
+
) -> Series:
|
154
|
+
"""Adjust a Series via its FFT frequencies."""
|
155
|
+
import utilities.numpy
|
156
|
+
|
157
|
+
array = series.to_numpy()
|
158
|
+
adjusted = utilities.numpy.adjust_frequencies(
|
159
|
+
array, filters=filters, weights=weights, d=d
|
160
|
+
)
|
161
|
+
return Series(name=series.name, values=adjusted, dtype=Float64)
|
162
|
+
|
163
|
+
|
164
|
+
##
|
165
|
+
|
166
|
+
|
144
167
|
def append_dataclass(df: DataFrame, obj: Dataclass, /) -> DataFrame:
|
145
168
|
"""Append a dataclass object to a DataFrame."""
|
146
169
|
non_null_fields = {k: v for k, v in asdict(obj).items() if v is not None}
|
@@ -658,6 +681,73 @@ def _cross_or_touch(
|
|
658
681
|
##
|
659
682
|
|
660
683
|
|
684
|
+
@overload
|
685
|
+
def cross_rolling_quantile(
|
686
|
+
expr: ExprLike,
|
687
|
+
up_or_down: Literal["up", "down"],
|
688
|
+
quantile: float,
|
689
|
+
/,
|
690
|
+
*,
|
691
|
+
interpolation: RollingInterpolationMethod = "nearest",
|
692
|
+
window_size: int = 2,
|
693
|
+
weights: list[float] | None = None,
|
694
|
+
min_samples: int | None = None,
|
695
|
+
center: bool = False,
|
696
|
+
) -> Expr: ...
|
697
|
+
@overload
|
698
|
+
def cross_rolling_quantile(
|
699
|
+
expr: Series,
|
700
|
+
up_or_down: Literal["up", "down"],
|
701
|
+
quantile: float,
|
702
|
+
/,
|
703
|
+
*,
|
704
|
+
interpolation: RollingInterpolationMethod = "nearest",
|
705
|
+
window_size: int = 2,
|
706
|
+
weights: list[float] | None = None,
|
707
|
+
min_samples: int | None = None,
|
708
|
+
center: bool = False,
|
709
|
+
) -> Series: ...
|
710
|
+
@overload
|
711
|
+
def cross_rolling_quantile(
|
712
|
+
expr: IntoExprColumn,
|
713
|
+
up_or_down: Literal["up", "down"],
|
714
|
+
quantile: float,
|
715
|
+
/,
|
716
|
+
*,
|
717
|
+
interpolation: RollingInterpolationMethod = "nearest",
|
718
|
+
window_size: int = 2,
|
719
|
+
weights: list[float] | None = None,
|
720
|
+
min_samples: int | None = None,
|
721
|
+
center: bool = False,
|
722
|
+
) -> Expr | Series: ...
|
723
|
+
def cross_rolling_quantile(
|
724
|
+
expr: IntoExprColumn,
|
725
|
+
up_or_down: Literal["up", "down"],
|
726
|
+
quantile: float,
|
727
|
+
/,
|
728
|
+
*,
|
729
|
+
interpolation: RollingInterpolationMethod = "nearest",
|
730
|
+
window_size: int = 2,
|
731
|
+
weights: list[float] | None = None,
|
732
|
+
min_samples: int | None = None,
|
733
|
+
center: bool = False,
|
734
|
+
) -> Expr | Series:
|
735
|
+
"""Compute when a column crosses its rolling quantile."""
|
736
|
+
expr = ensure_expr_or_series(expr)
|
737
|
+
rolling = expr.rolling_quantile(
|
738
|
+
quantile,
|
739
|
+
interpolation=interpolation,
|
740
|
+
window_size=window_size,
|
741
|
+
weights=weights,
|
742
|
+
min_samples=min_samples,
|
743
|
+
center=center,
|
744
|
+
)
|
745
|
+
return cross(expr, up_or_down, rolling)
|
746
|
+
|
747
|
+
|
748
|
+
##
|
749
|
+
|
750
|
+
|
661
751
|
def dataclass_to_dataframe(
|
662
752
|
objs: MaybeIterable[Dataclass],
|
663
753
|
/,
|
@@ -1027,6 +1117,20 @@ class _GetDataTypeOrSeriesTimeZoneNotZonedError(GetDataTypeOrSeriesTimeZoneError
|
|
1027
1117
|
##
|
1028
1118
|
|
1029
1119
|
|
1120
|
+
def get_frequency_spectrum(series: Series, /, *, d: int = 1) -> DataFrame:
|
1121
|
+
"""Get the frequency spectrum."""
|
1122
|
+
import utilities.numpy
|
1123
|
+
|
1124
|
+
array = series.to_numpy()
|
1125
|
+
spectrum = utilities.numpy.get_frequency_spectrum(array, d=d)
|
1126
|
+
return DataFrame(
|
1127
|
+
data=spectrum, schema={"frequency": Float64, "amplitude": Float64}, orient="row"
|
1128
|
+
)
|
1129
|
+
|
1130
|
+
|
1131
|
+
##
|
1132
|
+
|
1133
|
+
|
1030
1134
|
@overload
|
1031
1135
|
def get_series_number_of_decimals(
|
1032
1136
|
series: Series, /, *, nullable: Literal[True]
|
@@ -1736,6 +1840,7 @@ __all__ = [
|
|
1736
1840
|
"SetFirstRowAsColumnsError",
|
1737
1841
|
"StructFromDataClassError",
|
1738
1842
|
"YieldStructSeriesElementsError",
|
1843
|
+
"adjust_frequencies",
|
1739
1844
|
"append_dataclass",
|
1740
1845
|
"are_frames_equal",
|
1741
1846
|
"ceil_datetime",
|
@@ -1753,6 +1858,7 @@ __all__ = [
|
|
1753
1858
|
"finite_ewm_mean",
|
1754
1859
|
"floor_datetime",
|
1755
1860
|
"get_data_type_or_series_time_zone",
|
1861
|
+
"get_frequency_spectrum",
|
1756
1862
|
"get_series_number_of_decimals",
|
1757
1863
|
"insert_after",
|
1758
1864
|
"insert_before",
|
utilities/polars_ols.py
CHANGED
@@ -10,7 +10,9 @@ from utilities.functions import is_sequence_of
|
|
10
10
|
from utilities.polars import concat_series, ensure_expr_or_series
|
11
11
|
|
12
12
|
if TYPE_CHECKING:
|
13
|
-
from polars._typing import
|
13
|
+
from polars._typing import (
|
14
|
+
IntoExprColumn, # pyright: ignore[reportPrivateImportUsage]
|
15
|
+
)
|
14
16
|
from polars_ols import NullPolicy
|
15
17
|
|
16
18
|
from utilities.polars import ExprLike
|
File without changes
|
File without changes
|