Source code for energy_analysis_toolbox.power.overconsumption.find
"""Finds the overconsumption from a power series and a threshold."""
import pandas as pd
from energy_analysis_toolbox.power import basics as power
from energy_analysis_toolbox.timeseries.extract_features import intervals_over
[docs]
def from_power_threshold(
power_series: pd.Series,
overshoot_tshd: pd.Series | float,
reference_energy_tshd: pd.Series | float | None = None,
) -> pd.DataFrame:
"""Return a table of overconsumption where power_series is above overshoot_tshd.
The function also computes the overshoot energy as the energy of the difference
between ``power_series`` and ``reference_energy_tshd`` during the overshoot
overconsumption.
Parameters
----------
power_series : pd.Series
A timeseries of power measures in (W). The power in each element is
the averaged power during ``[ti, ti+1[`` where ``ti`` and ``ti+1`` are the
indices of the considered and next elements.
overshoot_tshd : pd.Series or float
The threshold in (W) over which the power is considered as
over-consumption. In case a series is given, it should have the
same index as ``power_series``.
reference_energy_tshd : pd.Series or float or None
A power in (W) to be subtracted from the power series in order
to compute an "overshoot energy" for each interval. The
default is |None| in which case ``overshoot_tshd`` is used.
In case a series is given, it should have the same index as
``power_series``.
Returns
-------
pd.DataFrame :
A table of overconsumption with the following columns :
- ``start`` : timestamp of the first instant of an overshoot interval;
- ``end`` : timestamp of the first instant after an overshoot interval;
- ``duration`` : duration in (s) of the overshoot interval. This is the
difference in (s) between the start and end bounds.
- ``energy`` : the energy associated to the difference between ``power_series``
and ``reference_energy_tshd`` during the ``[start, end[`` interval.
.. note:: Why use two thresholds ?
When looking for overconsumption, the threshold defining the "anomaly" of
the power may not be the reference VS which the overconsumption is computed.
E.g., the overconsumption may be computed VS the average consumption while the
abnormal overconsumption may be identified using variability-related thresholds.
This function provides both location and "overshoot-energy" computation for
convenience.
"""
if reference_energy_tshd is None:
reference_energy_tshd = overshoot_tshd
# Find overshoots of power threshold
if isinstance(overshoot_tshd, pd.Series):
power_series_aligned, overshoot_tshd_aligned = power_series.align(
overshoot_tshd,
)
else:
power_series_aligned, overshoot_tshd_aligned = (
power_series,
pd.Series(overshoot_tshd, index=power_series.index),
)
intervals_overshoot = intervals_over(
power_series_aligned > overshoot_tshd_aligned, 0.5,
)
if intervals_overshoot.empty:
intervals_overshoot["duration"] = []
intervals_overshoot["energy"] = []
else:
intervals_overshoot["duration"] = (
intervals_overshoot["end"] - intervals_overshoot["start"]
).dt.total_seconds()
# Compute energy criterion associated to overshoots
if isinstance(reference_energy_tshd, pd.Series):
power_series_aligned, reference_energy_tshd_aligned = power_series.align(
reference_energy_tshd,
)
else:
power_series_aligned, reference_energy_tshd_aligned = (
power_series,
pd.Series(reference_energy_tshd, index=power_series.index),
)
intervals_overshoot["energy"] = power.integrate_over(
intervals_overshoot, power_series - reference_energy_tshd_aligned,
)
return intervals_overshoot