Source code for dafpy.operations

"""
A ``Daf`` query can use operations to process the data: ``EltwiseOperation`` that preserve the shape of the data, and
``ReductionOperation`` that reduce a matrix to a vector, or a vector to a scalar. See the Julia
`documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html>`__ for details.
"""

from typing import AbstractSet
from typing import Callable
from typing import Optional
from typing import Type
from typing import Union
from typing import overload

import numpy as np
import pandas as pd  # type: ignore

from .julia_import import JlObject
from .julia_import import _given
from .julia_import import _to_julia_type
from .julia_import import jl
from .storage_types import StorageScalar

__all__ = [
    "QueryOperation",
    "QuerySequence",
    "EltwiseOperation",
    "ReductionOperation",
    "Abs",
    "Clamp",
    "Convert",
    "Fraction",
    "Log",
    "Max",
    "Median",
    "Mean",
    "Min",
    "Quantile",
    "Round",
    "Significant",
    "Std",
    "StdN",
    "Sum",
    "Var",
    "VarN",
]


class PendingNumpyQuery:
    """
    Used to implement ``query | daf.get_np_query()``.
    """

    def __init__(self, run: Callable) -> None:
        self.run = run


class PendingPandasQuery:
    """
    Used to implement ``query | daf.get_pd_query()``.
    """

    def __init__(self, run: Callable) -> None:
        self.run = run


[docs] class QueryOperation(JlObject): """ Base class for all query operations. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/registry.html#DataAxesFormats.Registry.QueryOperation>`__ for details. Query operations can be chained into a ``QuerySequence`` using the ``|`` operator in Python (instead of the ``|>`` operator in Julia). """ @overload def __or__(self, other: PendingNumpyQuery) -> StorageScalar | np.ndarray | AbstractSet[str]: ... @overload def __or__(self, other: PendingPandasQuery) -> StorageScalar | pd.Series | pd.DataFrame | AbstractSet[str]: ... @overload def __or__(self, other: "QueryOperation") -> "QuerySequence": ... def __or__( self, other: Union["QueryOperation", PendingNumpyQuery, PendingPandasQuery] ) -> Union["QuerySequence", StorageScalar, np.ndarray, pd.Series, pd.DataFrame, AbstractSet[str]]: if isinstance(other, (PendingNumpyQuery, PendingPandasQuery)): return other.run(self) return QuerySequence(jl.DataAxesFormats.QuerySequence(self, other))
[docs] class QuerySequence(QueryOperation): """ A sequence of ``QueryOperation``. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/queries.html#DataAxesFormats.Queries.QuerySequence>`__ for details. Query operations can be chained into a ``QuerySequence`` using the ``|`` operator in Python (instead of the ``|>`` operator in Julia). """
[docs] class EltwiseOperation(QueryOperation): """ Base class for all element-wise operations. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/registry.html#DataAxesFormats.Registry.EltwiseOperation>`__ for details. """
[docs] class ReductionOperation(QueryOperation): """ Abstract type for all reduction operations. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/registry.html#DataAxesFormats.Registry.ReductionOperation>`__ for details. """
[docs] class Abs(EltwiseOperation): """ Element-wise operation that converts every element to its absolute value. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Abs>`__ for details. """ def __init__(self, *, type: Optional[Type] = None) -> None: # pylint: disable=redefined-builtin super().__init__(jl.DataAxesFormats.Abs(type=_to_julia_type(type)))
[docs] class Round(EltwiseOperation): """ Element-wise operation that converts every element to the nearest integer value. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Round>`__ for details. """ def __init__(self, *, type: Optional[Type] = None) -> None: # pylint: disable=redefined-builtin super().__init__(jl.DataAxesFormats.Round(type=_to_julia_type(type)))
[docs] class Clamp(EltwiseOperation): """ Element-wise operation that converts every element to a value inside a range. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Clamp>`__ for details. """ def __init__( # pylint: disable=redefined-builtin self, *, min: Optional[float] = None, max: Optional[float] = None ) -> None: super().__init__(jl.DataAxesFormats.Clamp(**_given(min=min, max=max)))
[docs] class Convert(EltwiseOperation): """ Element-wise operation that converts every element to a given data type. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Convert>`__ for details. """ def __init__(self, *, type: Type) -> None: # pylint: disable=redefined-builtin super().__init__(jl.DataAxesFormats.Convert(type=_to_julia_type(type)))
[docs] class Fraction(EltwiseOperation): """ Element-wise operation that converts every element to its fraction out of the total. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Fraction>`__ for details. """ def __init__(self, *, type: Optional[Type] = None) -> None: # pylint: disable=redefined-builtin super().__init__(jl.DataAxesFormats.Fraction(type=_to_julia_type(type)))
[docs] class Log(EltwiseOperation): """ Element-wise operation that converts every element to its logarithm. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Log>`__ for details. """ def __init__( self, *, type: Optional[Type] = None, # pylint: disable=redefined-builtin base: Optional[float] = None, eps: Optional[float] = None, ) -> None: super().__init__(jl.DataAxesFormats.Log(type=_to_julia_type(type), **_given(base=base, eps=eps)))
[docs] class Significant(EltwiseOperation): """ Element-wise operation that zeros all "insignificant" values. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Significant>`__ for details. """ def __init__(self, *, high: float, low: Optional[float] = None) -> None: super().__init__(jl.DataAxesFormats.Significant(high=high, low=low))
[docs] class Sum(ReductionOperation): """ Reduction operation that sums elements. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Sum>`__ for details. """ def __init__(self, *, type: Optional[Type] = None) -> None: # pylint: disable=redefined-builtin super().__init__(jl.DataAxesFormats.Sum(type=_to_julia_type(type)))
[docs] class Min(ReductionOperation): """ Reduction operation that returns the minimal element. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Min>`__ for details. """ def __init__(self) -> None: super().__init__(jl.DataAxesFormats.Min())
[docs] class Median(ReductionOperation): """ Reduction operation that returns the median value. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Median>`__ for details. """ def __init__(self) -> None: super().__init__(jl.DataAxesFormats.Median())
[docs] class Quantile(ReductionOperation): """ Reduction operation that returns the quantile value, that is, a value such that a certain fraction of the values is lower. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Quantile>`__ for details. """ def __init__(self, *, type: Optional[Type] = None, p: float) -> None: # pylint: disable=redefined-builtin super().__init__(jl.DataAxesFormats.Quantile(type=_to_julia_type(type), p=p))
[docs] class Mean(ReductionOperation): """ Reduction operation that returns the mean value. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Mean>`__ for details. """ def __init__(self) -> None: super().__init__(jl.DataAxesFormats.Mean())
[docs] class Max(ReductionOperation): """ Reduction operation that returns the maximal element. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Max>`__ for details. """ def __init__(self) -> None: super().__init__(jl.DataAxesFormats.Max())
[docs] class Var(ReductionOperation): """ Reduction operation that returns the variance of the values. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Var>`__ for details. """ def __init__(self) -> None: super().__init__(jl.DataAxesFormats.Var())
[docs] class VarN(ReductionOperation): """ Reduction operation that returns the variance of the values, normalized (divided) by the mean of the values. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.VarN>`__ for details. """ def __init__(self) -> None: super().__init__(jl.DataAxesFormats.VarN())
[docs] class Std(ReductionOperation): """ Reduction operation that returns the standard deviation of the values. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.Std>`__ for details. """ def __init__(self) -> None: super().__init__(jl.DataAxesFormats.Std())
[docs] class StdN(ReductionOperation): """ Reduction operation that returns the standard deviation of the values, normalized (divided) by the mean of the values. See the Julia `documentation <https://tanaylab.github.io/DataAxesFormats.jl/v0.3.0/operations.html#DataAxesFormats.Operations.StdN>`__ for details. """ def __init__(self) -> None: super().__init__(jl.DataAxesFormats.StdN())