Fix "Get started"-docu

Summary

Running the Get-Started documentation from here gives an attribute error.

Python 3.9.4 SaQC 2.1 via PyPi

Reproducible Example

import numpy as np
import pandas as pd
from saqc import SaQC

# we need some dummy data
values = np.array([12, 24, 36, 33, 89, 87, 45, 31, 18, 99])
dates = pd.date_range(start="2020-01-01", periods=len(values), freq="D")
data = pd.DataFrame({"a": values}, index=dates)
# let's insert some constant values ...
data.iloc[3:6] = values.mean()
# ... and an outlier
data.iloc[8] = 175

# initialize saqc
qc = SaQC(data=data, scheme="simple")
# qc
qc = qc.flagRange("a", min=20, max=80)

What is the current bug behavior?

AttributeError: 'numpy.ndarray' object has no attribute 'empty'

What is the expected correct behavior?

Magic working out of the box

Stacktrace

Click to expand
In [10]: qc = qc.flagRange("a", min=20, max=80)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In [10], line 1
----> 1 qc = qc.flagRange("a", min=20, max=80)

File ~/.pyenv/versions/3.9.4/envs/test_saqc/lib/python3.9/site-packages/saqc/core/modules/outliers.py:118, in Outliers.flagRange(self, field, min, max, flag, **kwargs)
    109 @doc(saqc.funcs.outliers.flagRange.__doc__)
    110 def flagRange(
    111     self,
   (...)
    116     **kwargs,
    117 ) -> saqc.SaQC:
--> 118     return self._defer("flagRange", locals())

File ~/.pyenv/versions/3.9.4/envs/test_saqc/lib/python3.9/site-packages/saqc/core/modules/__init__.py:50, in FunctionsMixin._defer(self, fname, flocals)
     48 flocals.pop("self", None)
     49 fkwargs = flocals.pop("kwargs", {})
---> 50 return self._wrap(FUNC_MAP[fname])(**flocals, **fkwargs)

File ~/.pyenv/versions/3.9.4/envs/test_saqc/lib/python3.9/site-packages/saqc/core/core.py:214, in SaQC._wrap.<locals>.inner(field, target, regex, flag, *args, **kwargs)
    212         if not func.handles_target:
    213             fkwargs["field"] = fkwargs.pop("target")
--> 214         out = out._callFunction(func, *args, **fkwargs)
    216 return out

File ~/.pyenv/versions/3.9.4/envs/test_saqc/lib/python3.9/site-packages/saqc/core/core.py:228, in SaQC._callFunction(self, function, field, *args, **kwargs)
    220 def _callFunction(
    221     self,
    222     function: Callable,
   (...)
    225     **kwargs: Any,
    226 ) -> SaQC:
--> 228     res = function(data=self._data, flags=self._flags, field=field, *args, **kwargs)
    230     # keep consistence: if we modify data and flags inplace in a function,
    231     # but data is the original and flags is a copy (as currently implemented),
    232     # data and flags of the original saqc obj may change inconsistently.
    233     self._data, self._flags = res

File ~/.pyenv/versions/3.9.4/envs/test_saqc/lib/python3.9/site-packages/saqc/core/register.py:151, in FunctionWrapper.__call__(self, data, field, flags, *args, **kwargs)
    148 self._warn(columns.difference(self.data.columns).to_list(), source="mask")
    149 columns = columns.intersection(self.data.columns)
--> 151 masked, stored = self._maskData(
    152     data=self.data,
    153     flags=self.flags,
    154     columns=columns,
    155     thresh=self.mask_thresh,
    156 )
    157 self.data = masked
    158 self.stored_data = stored

File ~/.pyenv/versions/3.9.4/envs/test_saqc/lib/python3.9/site-packages/saqc/core/register.py:303, in FunctionWrapper._maskData(data, flags, columns, thresh)
    288 @staticmethod
    289 def _maskData(
    290     data: dios.DictOfSeries, flags: Flags, columns: Sequence[str], thresh: float
    291 ) -> Tuple[dios.DictOfSeries, dios.DictOfSeries]:
    292     """
    293     Mask data with Nans, if the flags are worse than a threshold.
    294         - mask only passed `columns` (preselected by `datamask`-kw from decorator)
   (...)
    301         dios holding iloc-data-pairs for every column in `data`
    302     """
--> 303     mask = dios.DictOfSeries(columns=columns)
    305     # we use numpy here because it is faster
    306     for c in columns:

File ~/.pyenv/versions/3.9.4/envs/test_saqc/lib/python3.9/site-packages/dios/dios/base.py:97, in _DiosBase.__init__(self, data, columns, index, itype, cast_policy, fastpath)
     93 # we try to infer the itype, but if we still have
     94 # no data, we will set the itype lazy, i.e. with
     95 # the first non-empty _insert()
     96 if itype is None:
---> 97     if self.empty:
     98         self._itype = "INFER"
     99     else:

File ~/.pyenv/versions/3.9.4/envs/test_saqc/lib/python3.9/site-packages/dios/dios/base.py:476, in _DiosBase.empty(self)
    433 @property
    434 def empty(self):
    435     """Indicator whether DictOfSeries is empty.
    436 
    437     Returns
   (...)
    474     True
    475     """
--> 476     return len(self) == 0 or all(s.empty for s in self._data)

File ~/.pyenv/versions/3.9.4/envs/test_saqc/lib/python3.9/site-packages/dios/dios/base.py:476, in <genexpr>(.0)
    433 @property
    434 def empty(self):
    435     """Indicator whether DictOfSeries is empty.
    436 
    437     Returns
   (...)
    474     True
    475     """
--> 476     return len(self) == 0 or all(s.empty for s in self._data)

AttributeError: 'numpy.ndarray' object has no attribute 'empty'

Possible fixes

qc = qc.flagRange("a", min=20, max=80)