diff --git a/saqc/core/modules/noise.py b/saqc/core/modules/noise.py index 527f2562c5bb04517d2ac3fb7e3262ad7f44cd8d..009b19a9ac1d28b714a699fd8c440eaf20f6af8a 100644 --- a/saqc/core/modules/noise.py +++ b/saqc/core/modules/noise.py @@ -13,6 +13,7 @@ from saqc.lib.types import ColumnName, FreqString, PositiveInt, PositiveFloat class Noise(ModuleBase): def flagByVarianceLowPass(self, field: ColumnName, + stat: Callable[[numpy.array, pd.Series], float], wnsz: FreqString, thresh: PositiveFloat, sub_wnsz: FreqString = None, diff --git a/saqc/funcs/noise.py b/saqc/funcs/noise.py index 57f4745a4fb9515ca9eab195b3e9cddfdd4fc2d4..9057f4d568ed7c3f7c30654aba8bc524bb4d981b 100644 --- a/saqc/funcs/noise.py +++ b/saqc/funcs/noise.py @@ -1,17 +1,21 @@ #! /usr/bin/env python # -*- coding: utf-8 -*- import pandas as pd +import numpy as np from dios import DictOfSeries +from typing import Callable from saqc.constants import * from saqc.core import register, Flags from saqc.lib.types import ColumnName, FreqString, PositiveInt, PositiveFloat +from saqc.lib.tools import getAttrOrApply @register(masking='field', module="noise") def flagByVarianceLowPass(data: DictOfSeries, field: ColumnName, flags: Flags, + stat: Callable[[np.array, pd.Series], float], wnsz: FreqString, thresh: PositiveFloat, sub_wnsz: FreqString = None, @@ -31,9 +35,11 @@ def flagByVarianceLowPass(data: DictOfSeries, wnsz = pd.Timedelta(wnsz) sub_wnsz = pd.Timedelta(sub_wnsz) - stat_parent = datcol.rolling(wnsz, min_periods=min_periods).std() + stat_parent = datcol.rolling(wnsz, min_periods=min_periods) + stat_parent = getAttrOrApply(stat_parent, stat) exceeding_parent = stat_parent > thresh - stat_sub = datcol.rolling(sub_wnsz).std() + stat_sub = datcol.rolling(sub_wnsz) + stat_sub = getAttrOrApply(stat_sub, stat) min_stat = stat_sub.rolling(wnsz - sub_wnsz, closed='both').min() exceeding_sub = min_stat > sub_thresh diff --git a/saqc/funcs/resampling.py b/saqc/funcs/resampling.py index 8bb871cddc7deb6cf8b6a762593089754647bb7d..36a326388c2020de98d9a68bbd256f0723210c79 100644 --- a/saqc/funcs/resampling.py +++ b/saqc/funcs/resampling.py @@ -605,7 +605,7 @@ def reindexFlags( flags: Flags, method: Literal[ "inverse_fagg", "inverse_bagg", "inverse_nagg", - "inverse_fshift", "inverse_bshift", "inverse_nshift" + "inverse_fshift", "inverse_bshift", "inverse_nshift", "match" ], source: str, freq: Optional[str] = None, diff --git a/saqc/lib/tools.py b/saqc/lib/tools.py index 1f15df6d0710e54610ce4a55b26b62c5c834c45e..3fe9c00d7aa7093ef7a52e727e3084008de566b0 100644 --- a/saqc/lib/tools.py +++ b/saqc/lib/tools.py @@ -532,3 +532,18 @@ def getFreqDelta(index): if i.equals(index): return i[1] - i[0] return delta + + +def getAttrOrApply(in_obj, apply_obj, attr_access='__name__', attr_or='apply'): + """ + For the repeating task of applying build in (accelerated) methods/funcs (`apply_obj`), + of rolling/resampling - like objects (`in_obj`) , + if those build-ins are available, or pass the method/func to the objects apply-like method, otherwise. + + """ + try: + out = getattr(in_obj, getattr(apply_obj, attr_access))() + except AttributeError: + out = getattr(in_obj, attr_or)(apply_obj) + + return out \ No newline at end of file