dycw-utilities 0.109.15__py3-none-any.whl → 0.109.17__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.15.dist-info → dycw_utilities-0.109.17.dist-info}/METADATA +1 -1
- {dycw_utilities-0.109.15.dist-info → dycw_utilities-0.109.17.dist-info}/RECORD +6 -6
- utilities/__init__.py +1 -1
- utilities/numpy.py +137 -2
- {dycw_utilities-0.109.15.dist-info → dycw_utilities-0.109.17.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.109.15.dist-info → dycw_utilities-0.109.17.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
utilities/__init__.py,sha256=
|
1
|
+
utilities/__init__.py,sha256=9W0BorEWmH8eCgNBXgx9zWKa3BNPPP1rlZfrx6qGCio,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=XMOaauVbssv_yrS1FdSnPExht3G4P8nAALmQsqHwp7w,25143
|
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
|
@@ -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.17.dist-info/METADATA,sha256=9BOdlf6JtDA2hK4ElsW-HsjxWLvub9HUqc1ds9r2CkY,13005
|
90
|
+
dycw_utilities-0.109.17.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
91
|
+
dycw_utilities-0.109.17.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
|
92
|
+
dycw_utilities-0.109.17.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/numpy.py
CHANGED
@@ -1,19 +1,23 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from functools import reduce
|
4
|
+
from functools import partial, reduce
|
5
5
|
from itertools import repeat
|
6
6
|
from typing import TYPE_CHECKING, Any, overload, override
|
7
7
|
|
8
8
|
import numpy as np
|
9
9
|
from numpy import (
|
10
|
+
argsort,
|
10
11
|
array,
|
11
12
|
bool_,
|
13
|
+
complex128,
|
12
14
|
digitize,
|
13
15
|
dtype,
|
14
16
|
errstate,
|
17
|
+
exp,
|
15
18
|
flatnonzero,
|
16
19
|
float64,
|
20
|
+
floating,
|
17
21
|
full_like,
|
18
22
|
inf,
|
19
23
|
int64,
|
@@ -30,6 +34,7 @@ from numpy import (
|
|
30
34
|
roll,
|
31
35
|
where,
|
32
36
|
)
|
37
|
+
from numpy.fft import fft, fftfreq, ifft
|
33
38
|
from numpy.linalg import det, eig
|
34
39
|
from numpy.random import default_rng
|
35
40
|
from numpy.typing import NDArray
|
@@ -37,7 +42,7 @@ from numpy.typing import NDArray
|
|
37
42
|
from utilities.iterables import is_iterable_not_str
|
38
43
|
|
39
44
|
if TYPE_CHECKING:
|
40
|
-
from collections.abc import Iterable
|
45
|
+
from collections.abc import Callable, Iterable
|
41
46
|
|
42
47
|
|
43
48
|
##
|
@@ -129,6 +134,65 @@ class AsIntError(Exception): ...
|
|
129
134
|
##
|
130
135
|
|
131
136
|
|
137
|
+
def boxcar(
|
138
|
+
array: NDArray[floating[Any]],
|
139
|
+
/,
|
140
|
+
*,
|
141
|
+
loc_low: float = -1.0,
|
142
|
+
slope_low: float = 1.0,
|
143
|
+
loc_high: float = 1.0,
|
144
|
+
slope_high: float = 1.0,
|
145
|
+
rtol: float | None = None,
|
146
|
+
atol: float | None = None,
|
147
|
+
) -> NDArray[floating[Any]]:
|
148
|
+
"""Construct a boxcar function."""
|
149
|
+
if not is_at_most(loc_low, loc_high, rtol=rtol, atol=atol):
|
150
|
+
raise _BoxCarLocationsError(low=loc_low, high=loc_high)
|
151
|
+
if not is_positive(slope_low, rtol=rtol, atol=atol):
|
152
|
+
raise _BoxCarLowerBoundSlopeError(slope=slope_low)
|
153
|
+
if not is_positive(slope_high, rtol=rtol, atol=atol):
|
154
|
+
raise _BoxCarUpperBoundSlopeError(slope=slope_high)
|
155
|
+
return (
|
156
|
+
sigmoid(array, loc=loc_low, slope=slope_low)
|
157
|
+
+ sigmoid(array, loc=loc_high, slope=-slope_high)
|
158
|
+
) / 2
|
159
|
+
|
160
|
+
|
161
|
+
@dataclass(kw_only=True, slots=True)
|
162
|
+
class BoxCarError(Exception): ...
|
163
|
+
|
164
|
+
|
165
|
+
@dataclass(kw_only=True, slots=True)
|
166
|
+
class _BoxCarLocationsError(BoxCarError):
|
167
|
+
low: float
|
168
|
+
high: float
|
169
|
+
|
170
|
+
@override
|
171
|
+
def __str__(self) -> str:
|
172
|
+
return f"Location parameters must be consistent; got {self.low} and {self.high}"
|
173
|
+
|
174
|
+
|
175
|
+
@dataclass(kw_only=True, slots=True)
|
176
|
+
class _BoxCarLowerBoundSlopeError(BoxCarError):
|
177
|
+
slope: float
|
178
|
+
|
179
|
+
@override
|
180
|
+
def __str__(self) -> str:
|
181
|
+
return f"Lower-bound slope parameter must be positive; got {self.slope}"
|
182
|
+
|
183
|
+
|
184
|
+
@dataclass(kw_only=True, slots=True)
|
185
|
+
class _BoxCarUpperBoundSlopeError(BoxCarError):
|
186
|
+
slope: float
|
187
|
+
|
188
|
+
@override
|
189
|
+
def __str__(self) -> str:
|
190
|
+
return f"Upper-bound slope parameter must be positive; got {self.slope}"
|
191
|
+
|
192
|
+
|
193
|
+
##
|
194
|
+
|
195
|
+
|
132
196
|
def discretize(x: NDArrayF, bins: int | Iterable[float], /) -> NDArrayF:
|
133
197
|
"""Discretize an array of floats.
|
134
198
|
|
@@ -160,6 +224,33 @@ def fillna(array: NDArrayF, /, *, value: float = 0.0) -> NDArrayF:
|
|
160
224
|
##
|
161
225
|
|
162
226
|
|
227
|
+
def filter_frequencies(
|
228
|
+
array: NDArrayF,
|
229
|
+
/,
|
230
|
+
*filters: Callable[[NDArray[floating[Any]]], NDArrayB],
|
231
|
+
d: int = 1,
|
232
|
+
) -> NDArrayF:
|
233
|
+
"""Filter an array by the frequencies of its FFT."""
|
234
|
+
(n,) = array.shape
|
235
|
+
fft_vals = fft(array)
|
236
|
+
freqs = fftfreq(n, d=d)
|
237
|
+
reduced = reduce(partial(_filter_frequencies_one, freqs=freqs), filters, fft_vals)
|
238
|
+
return ifft(reduced).real
|
239
|
+
|
240
|
+
|
241
|
+
def _filter_frequencies_one(
|
242
|
+
acc: NDArray[complex128],
|
243
|
+
el: Callable[[NDArray[floating[Any]]], NDArrayB],
|
244
|
+
/,
|
245
|
+
*,
|
246
|
+
freqs: NDArray[floating[Any]],
|
247
|
+
) -> NDArray[complex128]:
|
248
|
+
return where(el(freqs), acc, 0.0)
|
249
|
+
|
250
|
+
|
251
|
+
##
|
252
|
+
|
253
|
+
|
163
254
|
def flatn0(array: NDArrayB, /) -> int:
|
164
255
|
"""Return the index of the unique True element."""
|
165
256
|
if not array.any():
|
@@ -193,6 +284,19 @@ class FlatN0MultipleError(FlatN0Error):
|
|
193
284
|
##
|
194
285
|
|
195
286
|
|
287
|
+
def get_frequency_spectrum(array: NDArrayF, /, *, d: int = 1) -> NDArray[floating[Any]]:
|
288
|
+
"""Get the frequency spectrum."""
|
289
|
+
(n,) = array.shape
|
290
|
+
fft_vals = fft(array)
|
291
|
+
freqs = fftfreq(n, d=d)
|
292
|
+
amplitudes = np.abs(fft_vals)
|
293
|
+
data = np.hstack([freqs.reshape(-1, 1), amplitudes.reshape(-1, 1)])
|
294
|
+
return data[argsort(data[:, 0])]
|
295
|
+
|
296
|
+
|
297
|
+
##
|
298
|
+
|
299
|
+
|
196
300
|
def has_dtype(x: Any, dtype: Any, /) -> bool:
|
197
301
|
"""Check if an object has the required dtype."""
|
198
302
|
if is_iterable_not_str(dtype):
|
@@ -803,6 +907,31 @@ def shift_bool(
|
|
803
907
|
##
|
804
908
|
|
805
909
|
|
910
|
+
def sigmoid(
|
911
|
+
array: NDArray[floating[Any]],
|
912
|
+
/,
|
913
|
+
*,
|
914
|
+
loc: float = 0.0,
|
915
|
+
slope: float = 1.0,
|
916
|
+
rtol: float | None = None,
|
917
|
+
atol: float | None = None,
|
918
|
+
) -> NDArray[floating[Any]]:
|
919
|
+
"""Construct a sigmoid function."""
|
920
|
+
if is_zero(slope, rtol=rtol, atol=atol):
|
921
|
+
raise SigmoidError
|
922
|
+
return 1 / (1 + exp(-slope * (array - loc)))
|
923
|
+
|
924
|
+
|
925
|
+
@dataclass(kw_only=True, slots=True)
|
926
|
+
class SigmoidError(Exception):
|
927
|
+
@override
|
928
|
+
def __str__(self) -> str:
|
929
|
+
return "Slope must be non-zero"
|
930
|
+
|
931
|
+
|
932
|
+
##
|
933
|
+
|
934
|
+
|
806
935
|
def _is_close(
|
807
936
|
x: Any,
|
808
937
|
y: Any,
|
@@ -825,6 +954,7 @@ def _is_close(
|
|
825
954
|
__all__ = [
|
826
955
|
"DEFAULT_RNG",
|
827
956
|
"AsIntError",
|
957
|
+
"BoxCarError",
|
828
958
|
"FlatN0EmptyError",
|
829
959
|
"FlatN0Error",
|
830
960
|
"FlatN0MultipleError",
|
@@ -834,8 +964,10 @@ __all__ = [
|
|
834
964
|
"NDArrayI",
|
835
965
|
"NDArrayO",
|
836
966
|
"ShiftError",
|
967
|
+
"SigmoidError",
|
837
968
|
"array_indexer",
|
838
969
|
"as_int",
|
970
|
+
"boxcar",
|
839
971
|
"datetime64D",
|
840
972
|
"datetime64M",
|
841
973
|
"datetime64W",
|
@@ -851,7 +983,9 @@ __all__ = [
|
|
851
983
|
"datetime64us",
|
852
984
|
"discretize",
|
853
985
|
"fillna",
|
986
|
+
"filter_frequencies",
|
854
987
|
"flatn0",
|
988
|
+
"get_frequency_spectrum",
|
855
989
|
"has_dtype",
|
856
990
|
"is_at_least",
|
857
991
|
"is_at_least_or_nan",
|
@@ -902,4 +1036,5 @@ __all__ = [
|
|
902
1036
|
"maximum",
|
903
1037
|
"minimum",
|
904
1038
|
"shift_bool",
|
1039
|
+
"sigmoid",
|
905
1040
|
]
|
File without changes
|
File without changes
|