-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
ENH: Add support for calculating EWMA with a time component #34839
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f220181
a3d490f
f90f8a7
c7ce08b
66c9799
144bcaf
4297cae
d200bb7
f3e3b6b
7ee69be
be0ad74
28bf607
52fdea5
6059bc2
78f3399
f3925b4
9b53518
77d8c9d
6b630b3
4a214a1
7276505
62b9050
4d1535f
5300594
1f085f1
693bee2
1a4c61f
93bcb3d
ae8c7d2
7a707a2
016764f
d809e51
37962fb
90e2a28
5e45c3f
e2e875f
4a9c494
5a1f244
b9b3dfe
76a02b4
2d681aa
067e4fb
d0dff28
7477f0e
39c241d
999cffb
988a378
58ca9fc
c430349
a5c06de
e540287
a8e86e3
ed141d3
1debd80
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ from libc.stdlib cimport malloc, free | |
|
||
import numpy as np | ||
cimport numpy as cnp | ||
from numpy cimport ndarray, int64_t, float64_t, float32_t | ||
from numpy cimport ndarray, int64_t, float64_t, float32_t, uint8_t | ||
cnp.import_array() | ||
|
||
|
||
|
@@ -1752,6 +1752,51 @@ def roll_weighted_var(float64_t[:] values, float64_t[:] weights, | |
# ---------------------------------------------------------------------- | ||
# Exponentially weighted moving average | ||
|
||
def ewma_time(ndarray[float64_t] vals, int minp, ndarray[int64_t] times, | ||
int64_t halflife): | ||
""" | ||
Compute exponentially-weighted moving average using halflife and time | ||
distances. | ||
|
||
Parameters | ||
---------- | ||
vals : ndarray[float_64] | ||
minp : int | ||
times : ndarray[int64] | ||
halflife : int64 | ||
|
||
Returns | ||
------- | ||
ndarray | ||
""" | ||
cdef: | ||
Py_ssize_t i, num_not_nan = 0, N = len(vals) | ||
bint is_not_nan | ||
float64_t last_result | ||
ndarray[uint8_t] mask = np.zeros(N, dtype=np.uint8) | ||
ndarray[float64_t] weights, observations, output = np.empty(N, dtype=np.float64) | ||
|
||
if N == 0: | ||
return output | ||
|
||
last_result = vals[0] | ||
|
||
for i in range(N): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you you put this in a nogil block? do we have timings on this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried to
I can add an ASV for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok sure on the asv. I think you can convert the mask view to a np.take operation (but can always just add an issue for this) if needed |
||
is_not_nan = vals[i] == vals[i] | ||
num_not_nan += is_not_nan | ||
if is_not_nan: | ||
mask[i] = 1 | ||
weights = 0.5 ** ((times[i] - times[mask.view(np.bool_)]) / halflife) | ||
observations = vals[mask.view(np.bool_)] | ||
last_result = np.sum(weights * observations) / np.sum(weights) | ||
|
||
if num_not_nan >= minp: | ||
output[i] = last_result | ||
else: | ||
output[i] = NaN | ||
|
||
return output | ||
|
||
|
||
def ewma(float64_t[:] vals, float64_t com, bint adjust, bint ignore_na, int minp): | ||
""" | ||
|
@@ -1761,9 +1806,9 @@ def ewma(float64_t[:] vals, float64_t com, bint adjust, bint ignore_na, int minp | |
---------- | ||
vals : ndarray (float64 type) | ||
com : float64 | ||
adjust: int | ||
ignore_na: bool | ||
minp: int | ||
adjust : int | ||
ignore_na : bool | ||
minp : int | ||
|
||
Returns | ||
------- | ||
|
@@ -1831,10 +1876,10 @@ def ewmcov(float64_t[:] input_x, float64_t[:] input_y, | |
input_x : ndarray (float64 type) | ||
input_y : ndarray (float64 type) | ||
com : float64 | ||
adjust: int | ||
ignore_na: bool | ||
minp: int | ||
bias: int | ||
adjust : int | ||
ignore_na : bool | ||
minp : int | ||
bias : int | ||
|
||
Returns | ||
------- | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as a followup it should be possible to implement ewma with this one