Skip to content

chronulus.prediction

Prediction

A class representing the output of a prediction request

Parameters:

Name Type Description Default
_id str

Unique identifier for the prediction.

required

Attributes:

Name Type Description
_id str

Unique identifier for the prediction.

Source code in src/chronulus/prediction.py
class Prediction:
    """
    A class representing the output of a prediction request

    Parameters
    ----------
    _id : str
        Unique identifier for the prediction.

    Attributes
    ----------
    _id : str
        Unique identifier for the prediction.

    """

    def __init__(self, _id: str):
        self._id = _id

    @property
    def id(self) -> str:
        """Get the unique identifier for the prediction"""
        return self._id

id property

Get the unique identifier for the prediction

Forecast

Bases: Prediction

A class representing the output of a prediction request, containing both numerical results and explanatory text.

This class encapsulates the prediction results returned from the chronulus API, including a unique identifier, descriptive text, and the numerical predictions in a pandas DataFrame format.

Parameters:

Name Type Description Default
_id str

Unique identifier for the prediction.

required
text str

Descriptive text or notes explaining the prediction results.

required
data dict

JSON-Split formatted dictionary containing the prediction results.

required

Attributes:

Name Type Description
_id str

Unique identifier for the prediction.

_text str

Explanatory text describing the prediction results.

_data dict

JSON-Split formatted dictionary containing the prediction results.

Source code in src/chronulus/prediction.py
class Forecast(Prediction):
    """
    A class representing the output of a prediction request, containing both numerical results and explanatory text.

    This class encapsulates the prediction results returned from the chronulus API,
    including a unique identifier, descriptive text, and the numerical predictions in
    a pandas DataFrame format.

    Parameters
    ----------
    _id : str
        Unique identifier for the prediction.
    text : str
        Descriptive text or notes explaining the prediction results.
    data : dict
        JSON-Split formatted dictionary containing the prediction results.

    Attributes
    ----------
    _id : str
        Unique identifier for the prediction.
    _text : str
        Explanatory text describing the prediction results.
    _data : dict
        JSON-Split formatted dictionary containing the prediction results.

    """

    def __init__(self, _id: str, text: str, data: dict):
        super().__init__(_id)
        self._text = text
        self._data = data

    @property
    def data(self) -> dict:
        """Get the forecast data after the transformation defined by this forecast"""
        return self._transform_data(self._data)

    @property
    def text(self) -> str:
        """Get the forecast explanation after the transformation defined by this forecast"""
        return self._transform_text(self._text)

    def _transform_data(self, data: dict) -> dict:
        """Hook for transforming the forecast data"""
        return data

    def _transform_text(self, text: str) -> str:
        """Hook for transforming the forecast text"""
        return text

    def to_json(self, orient='columns'):
        """
        Convert the forecast data to JSON format with specified orientation.

        Parameters
        ----------
        orient : str, optional
            Data orientation for the JSON output. Options are:

            - 'split': Original JSON-split format
            - 'rows': List of dictionaries, each representing a row
            - 'columns': Dictionary of lists, each representing a column
            Default is 'columns'.

        Returns
        -------
        dict or list
            Forecast data in the specified JSON format:

            - For 'split': Original JSON-split dictionary
            - For 'rows': List of row dictionaries
            - For 'columns': Dictionary of column arrays

        Examples
        --------
        >>> # Get data in columns format
        >>> json_cols = forecast.to_json(orient='columns')
        >>> # Get data in rows format
        >>> json_rows = forecast.to_json(orient='rows')
        """

        if orient == 'split':
            return self.data

        elif orient == 'rows':
            columns = self.data.get('columns')
            rows = list()
            for row in self.data.get('data'):
                _row = {columns[j]: val for j, val in enumerate(row)}
                rows.append(_row)
            return rows

        else:
            col_names = self.data.get('columns')
            columns = {k: list() for k in col_names}

            for row in self.data.get('data'):
                for j, val in enumerate(row):
                    columns[col_names[j]].append(val)

            return columns

    def to_pandas(self):
        """
        Convert the forecast data to a pandas DataFrame.

        The first column is automatically set as the index of the resulting DataFrame.
        Typically, this is a timestamp or date column.

        Returns
        -------
        pandas.DataFrame
            DataFrame containing the forecast data with the first column as index.

        Raises
        ------
        UserWarning
            If pandas is not installed in the environment.

        Examples
        --------
        >>> df = forecast.to_pandas()
        >>> print(df.head())
                   y_hat
        date
        2025-01-01   .12345
        2025-01-02   .67890
        """
        if not PANDAS_AVAILABLE:
            warnings.warn(
                "pandas is not installed but his method requires pandas."
                "Please install pandas using `pip install pandas` and then try again.",
                UserWarning
            )
        else:
            json_str = json.dumps(self.data)
            df = pd.read_json(StringIO(json_str), orient='split')
            return df.set_index(self.data.get('columns')[0], drop=True)

data property

Get the forecast data after the transformation defined by this forecast

text property

Get the forecast explanation after the transformation defined by this forecast

to_json(orient='columns')

Convert the forecast data to JSON format with specified orientation.

Parameters:

Name Type Description Default
orient str

Data orientation for the JSON output. Options are:

  • 'split': Original JSON-split format
  • 'rows': List of dictionaries, each representing a row
  • 'columns': Dictionary of lists, each representing a column Default is 'columns'.
'columns'

Returns:

Type Description
dict or list

Forecast data in the specified JSON format:

  • For 'split': Original JSON-split dictionary
  • For 'rows': List of row dictionaries
  • For 'columns': Dictionary of column arrays

Examples:

>>> # Get data in columns format
>>> json_cols = forecast.to_json(orient='columns')
>>> # Get data in rows format
>>> json_rows = forecast.to_json(orient='rows')
Source code in src/chronulus/prediction.py
def to_json(self, orient='columns'):
    """
    Convert the forecast data to JSON format with specified orientation.

    Parameters
    ----------
    orient : str, optional
        Data orientation for the JSON output. Options are:

        - 'split': Original JSON-split format
        - 'rows': List of dictionaries, each representing a row
        - 'columns': Dictionary of lists, each representing a column
        Default is 'columns'.

    Returns
    -------
    dict or list
        Forecast data in the specified JSON format:

        - For 'split': Original JSON-split dictionary
        - For 'rows': List of row dictionaries
        - For 'columns': Dictionary of column arrays

    Examples
    --------
    >>> # Get data in columns format
    >>> json_cols = forecast.to_json(orient='columns')
    >>> # Get data in rows format
    >>> json_rows = forecast.to_json(orient='rows')
    """

    if orient == 'split':
        return self.data

    elif orient == 'rows':
        columns = self.data.get('columns')
        rows = list()
        for row in self.data.get('data'):
            _row = {columns[j]: val for j, val in enumerate(row)}
            rows.append(_row)
        return rows

    else:
        col_names = self.data.get('columns')
        columns = {k: list() for k in col_names}

        for row in self.data.get('data'):
            for j, val in enumerate(row):
                columns[col_names[j]].append(val)

        return columns

to_pandas()

Convert the forecast data to a pandas DataFrame.

The first column is automatically set as the index of the resulting DataFrame. Typically, this is a timestamp or date column.

Returns:

Type Description
DataFrame

DataFrame containing the forecast data with the first column as index.

Raises:

Type Description
UserWarning

If pandas is not installed in the environment.

Examples:

>>> df = forecast.to_pandas()
>>> print(df.head())
           y_hat
date
2025-01-01   .12345
2025-01-02   .67890
Source code in src/chronulus/prediction.py
def to_pandas(self):
    """
    Convert the forecast data to a pandas DataFrame.

    The first column is automatically set as the index of the resulting DataFrame.
    Typically, this is a timestamp or date column.

    Returns
    -------
    pandas.DataFrame
        DataFrame containing the forecast data with the first column as index.

    Raises
    ------
    UserWarning
        If pandas is not installed in the environment.

    Examples
    --------
    >>> df = forecast.to_pandas()
    >>> print(df.head())
               y_hat
    date
    2025-01-01   .12345
    2025-01-02   .67890
    """
    if not PANDAS_AVAILABLE:
        warnings.warn(
            "pandas is not installed but his method requires pandas."
            "Please install pandas using `pip install pandas` and then try again.",
            UserWarning
        )
    else:
        json_str = json.dumps(self.data)
        df = pd.read_json(StringIO(json_str), orient='split')
        return df.set_index(self.data.get('columns')[0], drop=True)

NormalizedForecast

Bases: Forecast

A class representing the output of a NormalizedForecast prediction request, containing both numerical results and explanatory text.

This class provides methods for operating on normalized forecast data.

Parameters:

Name Type Description Default
_id str

Unique identifier for the prediction.

required
text str

Descriptive text or notes explaining the prediction results.

required
data dict

JSON-Split formatted dictionary containing the prediction results.

required
y_min float

The minimum value of the source scale.

0.0
y_max float

The maximum value of the source scale

1.0
Source code in src/chronulus/prediction.py
class NormalizedForecast(Forecast):
    """
    A class representing the output of a NormalizedForecast prediction request, containing both numerical results and explanatory text.

    This class provides methods for operating on normalized forecast data.

    Parameters
    ----------
    _id : str
        Unique identifier for the prediction.
    text : str
        Descriptive text or notes explaining the prediction results.
    data : dict
        JSON-Split formatted dictionary containing the prediction results.
    y_min : float
        The minimum value of the source scale.
    y_max : float
        The maximum value of the source scale
    """

    def __init__(self, _id: str, text: str, data: dict, y_min: float = 0.0, y_max: float = 1.0):
        super().__init__(_id, text, data)
        self.y_min = y_min
        self.y_max = y_max

    def to_rescaled_forecast(self, y_min: float = 0.0, y_max: float = 1.0, invert_scale: bool = False):
        """
        Create a RescaledForecast instance from  NormalizedForecast object.

        This static method allows conversion from a generic Forecast to a RescaledForecast,
        applying the specified scaling parameters.

        Parameters
        ----------
        y_min : float, default 0.0
            The minimum value of the target scale.
        y_max : float, default 1.0
            The maximum value of the target scale.
        invert_scale : bool, default False
            Whether to invert the scale before rescaling.

        Returns
        -------
        RescaledForecast
            A new RescaledForecast instance containing the rescaled data.
        """
        return RescaledForecast(
            _id=self.id,
            data=self.data,
            text=self.text,
            y_min=y_min,
            y_max=y_max,
            invert_scale=invert_scale
        )

to_rescaled_forecast(y_min=0.0, y_max=1.0, invert_scale=False)

Create a RescaledForecast instance from NormalizedForecast object.

This static method allows conversion from a generic Forecast to a RescaledForecast, applying the specified scaling parameters.

Parameters:

Name Type Description Default
y_min float

The minimum value of the target scale.

0.0
y_max float

The maximum value of the target scale.

1.0
invert_scale bool

Whether to invert the scale before rescaling.

False

Returns:

Type Description
RescaledForecast

A new RescaledForecast instance containing the rescaled data.

Source code in src/chronulus/prediction.py
def to_rescaled_forecast(self, y_min: float = 0.0, y_max: float = 1.0, invert_scale: bool = False):
    """
    Create a RescaledForecast instance from  NormalizedForecast object.

    This static method allows conversion from a generic Forecast to a RescaledForecast,
    applying the specified scaling parameters.

    Parameters
    ----------
    y_min : float, default 0.0
        The minimum value of the target scale.
    y_max : float, default 1.0
        The maximum value of the target scale.
    invert_scale : bool, default False
        Whether to invert the scale before rescaling.

    Returns
    -------
    RescaledForecast
        A new RescaledForecast instance containing the rescaled data.
    """
    return RescaledForecast(
        _id=self.id,
        data=self.data,
        text=self.text,
        y_min=y_min,
        y_max=y_max,
        invert_scale=invert_scale
    )

RescaledForecast

Bases: Forecast

A class representing a RescaledForecast prediction

This class provides methods for rescaling (denormalizing) a Forecast.

Parameters:

Name Type Description Default
_id str

Unique identifier for the prediction.

required
text str

Descriptive text or notes explaining the prediction results.

required
data dict

JSON-Split formatted dictionary containing the prediction results.

required
y_min float

The minimum value of the source scale.

0.0
y_max float

The maximum value of the source scale

1.0
invert_scale bool

Should we invert the scale before rescaling?

False
Source code in src/chronulus/prediction.py
class RescaledForecast(Forecast):
    """
    A class representing a RescaledForecast prediction

    This class provides methods for rescaling (denormalizing) a Forecast.

    Parameters
    ----------
    _id : str
        Unique identifier for the prediction.
    text : str
        Descriptive text or notes explaining the prediction results.
    data : dict
        JSON-Split formatted dictionary containing the prediction results.
    y_min : float
        The minimum value of the source scale.
    y_max : float
        The maximum value of the source scale
    invert_scale : bool
        Should we invert the scale before rescaling?
    """

    def __init__(self, _id: str, text: str, data: dict, y_min: float = 0.0, y_max: float = 1.0, invert_scale: bool = False):
        super().__init__(_id, text, data)
        self.y_min = y_min
        self.y_max = y_max
        self.invert_scale = invert_scale

    def _transform_data(self, data: dict) -> dict:

        # data should be in split format
        # we should create types for this instead of assuming
        new_data = deepcopy(data)
        json_data = new_data.get("data")
        for i, (ds, y_hat) in enumerate(json_data):
            yhat = 1 - y_hat if self.invert_scale else y_hat
            yhat = yhat * (self.y_max - self.y_min) + self.y_min
            json_data[i][1] = yhat

        new_data['data'] = json_data

        return new_data

    @staticmethod
    def from_forecast(forecast: Forecast, y_min: float = 0.0, y_max: float = 1.0, invert_scale: bool = False):
        """
        Convert the normalized forecast to a rescaled forecast with specified scale parameters.

        This method creates a new RescaledForecast instance using the current forecast's data,
        allowing you to specify the target range and whether to invert the scale.

        Parameters
        ----------
        y_min : float, default 0.0
            The minimum value of the target scale.
        y_max : float, default 1.0
            The maximum value of the target scale.
        invert_scale : bool, default False
            Whether to invert the scale before rescaling.

        Returns
        -------
        RescaledForecast
            A new forecast instance with values rescaled to the specified range.
        """

        return RescaledForecast(
            _id=forecast.id,
            data=forecast.data,
            text=forecast.text,
            y_min=y_min,
            y_max=y_max,
            invert_scale=invert_scale
        )

from_forecast(forecast, y_min=0.0, y_max=1.0, invert_scale=False) staticmethod

Convert the normalized forecast to a rescaled forecast with specified scale parameters.

This method creates a new RescaledForecast instance using the current forecast's data, allowing you to specify the target range and whether to invert the scale.

Parameters:

Name Type Description Default
y_min float

The minimum value of the target scale.

0.0
y_max float

The maximum value of the target scale.

1.0
invert_scale bool

Whether to invert the scale before rescaling.

False

Returns:

Type Description
RescaledForecast

A new forecast instance with values rescaled to the specified range.

Source code in src/chronulus/prediction.py
@staticmethod
def from_forecast(forecast: Forecast, y_min: float = 0.0, y_max: float = 1.0, invert_scale: bool = False):
    """
    Convert the normalized forecast to a rescaled forecast with specified scale parameters.

    This method creates a new RescaledForecast instance using the current forecast's data,
    allowing you to specify the target range and whether to invert the scale.

    Parameters
    ----------
    y_min : float, default 0.0
        The minimum value of the target scale.
    y_max : float, default 1.0
        The maximum value of the target scale.
    invert_scale : bool, default False
        Whether to invert the scale before rescaling.

    Returns
    -------
    RescaledForecast
        A new forecast instance with values rescaled to the specified range.
    """

    return RescaledForecast(
        _id=forecast.id,
        data=forecast.data,
        text=forecast.text,
        y_min=y_min,
        y_max=y_max,
        invert_scale=invert_scale
    )