From 9d5cd73115149ab6b048c6fc3ddd14a704ecb5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20M=C3=BCller?= <mueller.seb@posteo.de> Date: Tue, 29 Aug 2023 13:39:04 +0200 Subject: [PATCH] data: add tools for masked arrays --- src/finam/data/__init__.py | 8 +++++ src/finam/data/tools.py | 66 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/finam/data/__init__.py b/src/finam/data/__init__.py index 9edf5a82..836f98ea 100644 --- a/src/finam/data/__init__.py +++ b/src/finam/data/__init__.py @@ -88,12 +88,15 @@ from .tools import ( assert_type, check, check_quantified, + filled, full, full_like, get_dimensionality, get_magnitude, get_units, + has_masked_values, has_time_axis, + is_masked_array, is_quantified, prepare, quantify, @@ -141,3 +144,8 @@ __all__ += [ "to_datetime", "to_units", ] +__all__ += [ + "is_masked_array", + "has_masked_values", + "filled", +] diff --git a/src/finam/data/tools.py b/src/finam/data/tools.py index 9aee2a61..9484f685 100644 --- a/src/finam/data/tools.py +++ b/src/finam/data/tools.py @@ -433,6 +433,72 @@ def is_quantified(xdata): return isinstance(xdata, pint.Quantity) +def is_masked_array(xdata): + """ + Check if data is a masked array. + + Parameters + ---------- + xdata : Any + The given data array. + + Returns + ------- + bool + Whether the data is a MaskedArray. + """ + if is_quantified(xdata): + return np.ma.isMaskedArray(xdata.magnitude) + return np.ma.isMaskedArray(xdata) + + +def has_masked_values(xdata): + """ + Determine whether the data has masked values. + + Parameters + ---------- + xdata : Any + The given data array. + + Returns + ------- + bool + Whether the data is a MaskedArray and has any masked values. + """ + if is_quantified(xdata): + return np.ma.is_masked(xdata.magnitude) + return np.ma.is_masked(xdata) + + +def filled(xdata, fill_value=None): + """ + Return a filled array if the data is masked. + + Parameters + ---------- + xdata : :class:`pint.Quantity` or :class:`numpy.ndarray` or :class:`numpy.ma.MaskedArray` + The reference object input. + fill_value : array_like, optional + The value to use for invalid entries. Can be scalar or non-scalar. + If non-scalar, the resulting ndarray must be broadcastable over + input array. Default is None, in which case, the `fill_value` + attribute of the array is used instead. + + Returns + ------- + pint.Quantity or numpy.ndarray + New object with the same shape and type as other, + with the data filled with fill_value. + Units will be taken from the input if present. + """ + if not is_masked_array(xdata): + return xdata + if is_quantified(xdata): + return UNITS.Quantity(xdata.magnitude.filled(fill_value), xdata.units) + return xdata.filled(fill_value) + + def quantify(xdata, units=None): """ Quantifies data. -- GitLab