Source code for nrv.backend._extlib_interface

"""
Module containing functions to ease and addapt the interface with external libraries
"""

import numpy as np
from pandas import DataFrame
from typing import Literal

# ---------------------------------- #
#       Numpy compatibility          #
# ---------------------------------- #


[docs] def is_empty_iterable(x): """ check if the object x is an empty iterable Parameters ---------- x : any object to check. Returns ------- bool """ if not np.iterable(x): return False if len(x) == 0: return True return False
[docs] def set_idxs(_i: np.ndarray | int | tuple | None, _n: int | None) -> np.ndarray: """ convert an object _i into an 1D array of index Parameters ---------- _i : np.ndarray | int | tuple | None Indexes considered, can be either: - None (default): all indexes from 0 to ``_n-1`` - int: single indexe corresponding to _i - tuple: all indexes between _i[0] and _i[1] _n : int | None Indexes number when _i is `None` Returns ------- np.ndarray """ if _i is None and _n is not None: _i = np.arange(_n) elif not np.iterable(_i): _i = np.array([_i]) elif isinstance(_i, tuple) and len(_i) == 2: _i = np.arange(*_i) elif isinstance(_i, list): _i = np.array(_i) if isinstance(_i, np.ndarray) and _n is not None: _i = _i[_i < _n] return _i
def np_trapz(*args, **kwgs): """ Wrap NumPy trapezoidal integration with version-compatible dispatch. Returns the result of :func:``np.trapz`` for NumPy versions older than 2.0.0 and :func:``np.trapezoid`` otherwise. """ if np.__version__ < "2.0.0": return np.trapz(*args, **kwgs) return np.trapezoid(*args, **kwgs) # ---------------------------------- # # Pandas compatibility # # ---------------------------------- #
[docs] def get_query(*args, **kwgs): """ Convert a list of kwargs into a `str` compatible with pandas.DataFrame.query """ queries = [] for expr in args: if isinstance(expr, str): queries += [expr] for i_lab, i_val in kwgs.items(): if i_val is not None: if isinstance(i_val, str): queries += [i_val] elif isinstance(i_val, dict): queries += [get_query(**i_val)] else: queries += [f"{i_lab}.isin({set_idxs(i_val, None).tolist()})"] if len(queries) == 0: return None queries = " and ".join(queries) return queries
[docs] def df_to( df: DataFrame, otype: None | Literal["numpy", "list"], *args, **kwgs ) -> object: """ convert a :class:`pandas.DataFrame` to another type. Note ---- This function if a generalisation of all `pandas.DataFrame` methods `to_...`. In other words, if otype is not None, this function returns: `f"df.to_{otype}(*args, **kwgs)"` Parameters ---------- df : DataFrame :class:`pandas.DataFrame` to convert. otype : None | Literal[&quot;numpy&quot;, &quot;list&quot;] If None, return as a panda, convert into the corresponding class. Returns ------- _type_ _description_ """ if otype is None: return df else: to_any = eval(f"df.to_{otype}") return to_any(*args, **kwgs)