Source code for tafra.formatter

"""
Tafra: a minimalist dataframe

Copyright (c) 2020 Derrick W. Turk and David S. Fulford

Author
------
Derrick W. Turk
David S. Fulford

Notes
-----
Created on April 25, 2020
"""
from typing import Callable, Dict, Tuple, Any, Iterator, MutableMapping, Type, Optional

import numpy as np


[docs]class ObjectFormatter(Dict[str, Callable[[np.ndarray], np.ndarray]], MutableMapping[str, Callable[[np.ndarray], np.ndarray]]): """ A dictionary that contains mappings for formatting objects. Some numpy objects should be cast to other types, e.g. the :class:`decimal.Decimal` type cannot operate with :class:`np.float`. These mappings are defined in this class. Each mapping must define a function that takes a :class:`np.ndarray` and returns a :class:`np.ndarray`. The key for each mapping is the name of the type of the actual value, looked up from the first element of the :class:`np.ndarray`, i.e. ``type(array[0]).__name__``. """ test_array = np.arange(4)
[docs] def __setitem__(self, dtype: str, value: Callable[[np.ndarray], np.ndarray]) -> None: """ Set the dtype formatter. """ try: if not isinstance(value(self.test_array), np.ndarray): raise ValueError( 'Must provide a function that takes an ``np.ndarray`` and returns ' 'an np.ndarray.') except Exception as e: raise ValueError( 'Must provide a function that takes an ``np.ndarray`` and returns ' 'an np.ndarray.') dict.__setitem__(self, dtype, value)
[docs] def __getitem__(self, dtype: str) -> Callable[[np.ndarray], np.ndarray]: """ Get the dtype formatter. """ return dict.__getitem__(self, dtype)
[docs] def __delitem__(self, dtype: str) -> None: """ Delete the dtype formatter. """ dict.__delitem__(self, dtype)
def __repr__(self) -> str: return self.__str__() def __str__(self) -> str: if self.__len__() < 1: return r'{}' return '{' + '\n'.join(f'{c}: {v}' for c, v in self.items()) + '}' def __iter__(self) -> Iterator[Any]: yield from dict.__iter__(self) def __len__(self) -> int: return dict.__len__(self) def copy(self) -> Dict[str, Any]: return {k: dict.__getitem__(self, k) for k in self} def parse_dtype(self, value: np.ndarray) -> Optional[np.ndarray]: """ Parse an object dtype. Parameters ---------- value: np.ndarray The :class:`np.ndarray` to be parsed. Returns ------- value, modified: Tuple(np.ndarray, bool) The :class:`np.ndarray` and whether it was modified or not. """ if value.dtype != np.dtype(object): return None type_name = type(value[0]).__name__ if type_name in self.keys(): value = self[type_name](value) return value return None