Add `Viz.median_from_range()`

A super snappy `numpy.median()` calculator (per input range) which we
slap an `lru_cache` on thanks to handy dunder method hacks for such
things on mutable types XD
multichartz_backup
Tyler Goodlet 2023-01-23 20:22:45 -05:00
parent fb9156ebc5
commit 0480b5e08a
1 changed files with 29 additions and 0 deletions

View File

@ -19,6 +19,7 @@ Data vizualization APIs
''' '''
from __future__ import annotations from __future__ import annotations
from functools import lru_cache
from math import ( from math import (
ceil, ceil,
floor, floor,
@ -282,6 +283,21 @@ class Viz(msgspec.Struct): # , frozen=True):
tuple[float, float], tuple[float, float],
] = {} ] = {}
# cache of median calcs from input read slice hashes
# see `.median()`
_meds: dict[
int,
float,
] = {}
# to make lru_cache-ing work, see
# https://docs.python.org/3/faq/programming.html#how-do-i-cache-method-calls
def __eq__(self, other):
return self._shm._token == other._shm._token
def __hash__(self):
return hash(self._shm._token)
@property @property
def shm(self) -> ShmArray: def shm(self) -> ShmArray:
return self._shm return self._shm
@ -462,6 +478,19 @@ class Viz(msgspec.Struct): # , frozen=True):
mxmn, mxmn,
) )
@lru_cache(maxsize=6116)
def median_from_range(
self,
start: int,
stop: int,
) -> float:
in_view = self.shm.array[start:stop]
if self.is_ohlc:
return np.median(in_view['close'])
else:
return np.median(in_view[self.name])
def view_range(self) -> tuple[int, int]: def view_range(self) -> tuple[int, int]:
''' '''
Return the start and stop x-indexes for the managed ``ViewBox``. Return the start and stop x-indexes for the managed ``ViewBox``.