Source code for perda.core_data_structures.masking

from __future__ import annotations

from enum import Enum
from typing import Callable

from .data_instance import DataInstance


[docs] class FilterOptions(Enum): """Specifies which array(s) a filter function receives as input.""" VALUES = "left_only" TIMESTAMPS = "right_only" BOTH = "both"
[docs] def apply_ufunc_filter( data: DataInstance, filter_func: Callable, apply_to: FilterOptions = FilterOptions.VALUES, ) -> DataInstance: """ Apply a filter function to a DataInstance. Parameters ---------- data : DataInstance Input DataInstance filter_func : Callable Function that takes in values and/or timestamps and returns a boolean mask apply_to : FilterOptions, optional Whether to apply the filter to values, timestamps, or both. Default is values Returns ------- DataInstance Filtered DataInstance Notes ----- The mask must come from this DataInstance's own arrays. To filter one signal by another (e.g. torque only while moving), align them with ``left_join_data_instances`` first, since signals logged at different rates have different lengths. Examples -------- >>> from perda.core_data_structures import FilterOptions, apply_ufunc_filter >>> voltage = aly.data["bms.pack.voltage"] >>> valid = apply_ufunc_filter(voltage, lambda values: values > 0) >>> late = apply_ufunc_filter( ... voltage, lambda ts: ts > ts[0] + 60_000_000, apply_to=FilterOptions.TIMESTAMPS ... ) """ if apply_to == FilterOptions.VALUES: mask = filter_func(data.value_np) elif apply_to == FilterOptions.TIMESTAMPS: mask = filter_func(data.timestamp_np) else: mask = filter_func(data.timestamp_np, data.value_np) return DataInstance( timestamp_np=data.timestamp_np[mask], value_np=data.value_np[mask], label=data.label, var_id=data.var_id, cpp_name=data.cpp_name, )