energy_analysis_toolbox.timeseries.resample.conservative module#
Convert power timeseries of flows and volumes without breaking conservation laws.
- energy_analysis_toolbox.timeseries.resample.conservative.deduce_flows(volumes: Series, last_step_duration: float | None = None) Series[source]#
Return a timeseries of “flow-rates” from one of an extensive variable.
- Parameters:
volumes (pd.Series) – The timeseries of “volumes” (X). In practice, any extensive variable which “flows” during the overconsumption of the series. The series is assumed to be indexed such that the value at a certain index is the volume which flows until the next index.
last_step_duration (float, optional) – Duration of the last time-step in the series in (s). The default is
Nonemeaning that the same duration as the former-last one is used.
- Returns:
pd.Series – The series of flow-rates in (X.s-1).
Notes
The flow-rate is simply obtained as the ratio between the volume flowing during each time-step VS the time-step duration.
As the values in the series are volumes consumed until the next index, the duration to be associated with the last element in the series is ambiguous. The chosen value is controlled by
last_step_durationargument.
- energy_analysis_toolbox.timeseries.resample.conservative.flow_rate_conservative(flow_rates: Series, target_instants: DatetimeIndex, last_step_duration: float | None = None, last_target_step_duration: float | None = None) Series[source]#
Return the series of flow-rate on target instants.
In what follows, flow-rates and volumes are considered in a broad meaning of these terms :
volumes represent amounts of an extensive variable which is subjected to a conservation law, such as actual volume of water (under certain assumptions), or mass, or energy;
flow-rates represent flows of this variable, such as volumic flow-rate, mass flow-rate or power.
- Parameters:
flow_rates (pd.Series) – Timeseries of flow-rates from which to interpolate in (X.s-1) where X is any extensive variable.
target_instants (pd.DatetimeIndex) – Instants at which the flow-rates values have to be returned.
last_step_duration (float, optional) – Duration of the last time-step in the series in (s). The default is
Nonein which case the duration of the former-last time-step is used.last_target_step_duration (float, optional) – Duration of the last time-step in the returned series in (s). The default is
Nonein which case the duration of the former-last time-step is used. This duration is used to deduce, if any, what proportion of the volume consumption implicitly defined by theflow_ratesseries located after the last target instant should be attributed to this instant.
Important
The
flow_ratesseries is assumed to be indexed such that the value at timetiis the flow-rate during the interval[ti, ti+1[until the next value in the series.See also
volume_conservativewhich resamples the consumed volumes on each interval.- Raises:
EATEmptySourceError : – In case
flow_ratesis empty.EATEmptyTargetsError : – In case
target_instantsis empty.EATInvalidTimestepDurationError : – In case
last_step_duration <= 0EATInvalidTimestepDurationError : – In case
last_target_step_duration <= 0
Note
Uncaught zero-division error will be encountered in case there is a null timestep in the source or target values.
- Returns:
pd.Series – Flow-rates values in interpolated at the target instants.
Notes
The flow-rates are interpolated in such a way that the “volume is conserved”. This means that the volume obtained when integrating the resampled flow-rate between two indices in the series should be the same as when computing this volume from the initial series.
The algorithm used by the function is the following :
First, the interval durations are computed. The last interval duration ambiguity is removed thanks to
last_step_duration. [1.]A series of “volumes” consumed during each timestep is created. This is the series of the flow-rate integrals over the time-step in the series assuming the
flow_ratesseries defines a piecewise constant function. [2.]The volumes are resampled in a conservative way using
energy_analysis_toolbox.timeseries.power.volume_conservativefunction. [3.]The resulting flow-rates are deduced as the ratio between these volumes and the interval durations of the target series. The duration of the last interval is defined by
last_target_step_duration. [4.]
- energy_analysis_toolbox.timeseries.resample.conservative.flow_rate_to_freq(series: pd.Series[float], freq: str | Timedelta, origin: None | Literal['floor', 'ceil'] | Timestamp = None, last_step_duration: float | None = None) pd.Series[float][source]#
Return a series resampled to freq such that the flow rate is conserved.
The last step duration of the resampled series is set to the frequency
freq.- Parameters:
series (pd.Series) – A series of values of a flow_rate-alike quantity with a DatetimeIndex. The sampling period can be constant or not (in this case, use
last_step_durationargument).freq (str, pd.Timedelta) – the freq to which the series is resampled. Must be a valid pandas frequency.
origin ({None, 'floor, 'ceil', pd.Timestamp}, optional) – What origin should be used for the target resampling range. See
index_to_freqfor details.last_step_duration (float, optional) – Duration of the last time-step in the
seriesin (s). The default isNonein which case the duration of the former-last time-step is used. This duration is used to deduce the volume in the last time-step as well as the last index of the resampled series.
- Returns:
pd.Series – The resampled series.
See also
flow_rate_conservativewhich resamples the flow-rate on the target instants.volume_to_freqwhich resamples the volume on the giver frequency.
- energy_analysis_toolbox.timeseries.resample.conservative.volume_conservative(volumes: Series, target_instants: DatetimeIndex, last_step_duration: float | None = None, last_target_step_duration: float | None = None) Series[source]#
Resample the volume on target instants assuming it is a conservative variable.
In what follows, flow-rates and volumes are considered in a broad meaning of these terms :
volumes represent amounts of an extensive variable such as actual volume of water, or mass, or energy;
flow-rates represent flows of this variable, such as volumic flow-rate, mass flow-rate or power.
The resampling is conservative in the sense that :
assuming that
volumesdefines a piecewise constant function defined on[closed, open[overconsumption (i.e. constant flow-rate between timesteps),the integral of the function defined by the interpolated volume series is always equal to which of the function defined by
volumeson the same support.
- Parameters:
volumes (pd.Series) – The timeseries of volumes in (X). X is the unit of an “extensive” variable which can flow along time. The series is assumed to be indexed such that the value at a certain index is the volume consumed until the next index.
target_instants (pd.DatetimeIndex) – Instants at which the flow-rates values have to be returned.
last_step_duration (float, optional) – Duration of the last time-step in the
volumeseries in (s). The default isNonein which case the duration of the former-last time-step is used. This duration is used to deduce the flow-rate in the last time-step.last_target_step_duration (float, optional) – Duration of the last time-step in the returned series in (s). The default is
Nonein which case the duration of the former-last time-step is used. This duration is used to deduce, if any, what proportion of the volume in thevolumesseries located after the last target instant should be attributed to this instant.
- Returns:
pd.Series – The volumes series sampled on the overconsumption defined in
target_instants.- Raises:
EATEmptySourceError : – In case
volumesis empty.EATEmptyTargetsError : – In case
target_instantsis empty.EATInvalidTimestepDurationError : – In case
last_step_duration <= 0.EATInvalidTimestepDurationError : – In case
last_target_step_duration <= 0.
Example
This function can resample extensive variables (typically, volumes) which consumption is spread along time using non-matching indices. It assumes a constant flux in order to ensure the conservation of the integrated variable on the new sampling overconsumption.
>>> volumes = pd.Series( np.array([0, 0.1, 0.05, 0.08]), index=pd.date_range("2021-12-15", periods=4, freq='6h') ) >>> volumes 2021-12-15 00:00:00 0.00 2021-12-15 06:00:00 0.10 2021-12-15 12:00:00 0.05 2021-12-15 18:00:00 0.08 Freq: 6H, dtype: float64 >>> target_index = pd.date_range("2021-12-15", periods=3, freq='8h') >>> volumes_obtained = volume_conservative(volumes, target_index) >>> volumes_obtained 2021-12-15 00:00:00 0.033333 2021-12-15 08:00:00 0.100000 2021-12-15 16:00:00 0.096667
As the timeseries of extensive variables defined a consumption spread on an interval, the last step duration is ambiguous. An arbitrary duration can be enforced using the
last_step_durationargument.>>> volumes = pd.Series( np.array([0.1]), index=pd.date_range("2021-12-15", periods=1, freq='1d') ) 2021-12-15 0.1 Freq: D, dtype: float64 >>> volumes >>> target_index = pd.date_range("2021-12-15", periods=4, freq='6h') >>> volumes_obtained = volume_conservative(volumes, target_index, last_step_duration=SK.day) >>> volumes_obtained 2021-12-15 00:00:00 0.025 2021-12-15 06:00:00 0.025 2021-12-15 12:00:00 0.025 2021-12-15 18:00:00 0.025 Freq: 6H, dtype: float64
This is also true and applicable for the last target step duration.
>>> target_index = pd.date_range("2021-12-15", periods=1, freq='12h') >>> volumes_obtained = volume_conservative( volumes, target_index, last_step_duration=SK.day, last_target_step_duration=SK.day / 2) >>> volumes_obtained 2021-12-15 0.05 Freq: 12H, dtype: float64
Padding the source series with zeros until the desired end of resampling can also ease removing the ambiguity on the “operative” part of the input data.
Notes
The volumes are resampled in such a way that for
tiandti+1two consecutive indices intarget_instants, the resampled volume associated withtiis the volume “consumed” during[ti, ti+1[, assuming a constant flow-rate during the time-overconsumption defined involumes.Accordingly, the function computes the resampled volumes as follows :
Compute the cumulated sum of volumes for each time-step. [1.]
Add a virtual timestep at the end of the volume series located
last_step_durationafter the last sample, with dummy value. [2.]As the
volumesseries was indexed in a way that element at timetwas the volume which flows betweentand the next timestep the cumulated series is shifted by one step on the right and left-padded with a zero. This way, element at positiontis the total volume which has flowed until timet. [3.]Also add a virtual timestep in the target series so that the cumulated sum at the implicit end of the target series is computed as well. [4.1]
Interpolate the series of cumulated volumes as a piecewise affine function. Target timesteps outside the convex span of the source-indices (including the fictive one) are assigned the corresponding border value:
0 before the beginning of the
volumesseriesThe total cumulated volume after the end of the volume series
This is consistent with the fact that no volume flow is considered outside the overconsumption defined in the series. [4.2]
Compute elementwise differences of the cumulated volume series, which returns the series of volume “consumed” between each timestep and the previous one. [5.]
Shift the obtained result one time-step backward in order to match the volume-series sampling convention. [6.]
Discard the last fictive time-step which has no meaning in this convention. [7.]
As the flow-rate is the time-derivative of the cumulated consumption curve, using a piecewise linear interpolation is equivalent to assuming a constant flow-rate during all the time-steps of the
volumesseries.Note
Why does this function work ? I.e. why does it conserve the volume ? Short explanation “with hands” :
The sampling convention of the
volumesseries is just an indirect way of defining a piecewise constant flow-rate function. The current method works by resampling exactly the integral of the flow-rate function, to, then, recover a new volume series (piecewise constant flow-rate function). By construction, the integral of the resulting piecewise constant flow-rate function on the overconsumption of its support of definition matches which of the original oneSee also
flow_rate_conservativewhich resamples the flow-rate on the time-overconsumption in a volume-conservative way.
- energy_analysis_toolbox.timeseries.resample.conservative.volume_to_freq(series: pd.Series[float], freq: str | Timedelta, origin: None | Literal['floor', 'ceil'] | Timestamp = None, last_step_duration: float | None = None) pd.Series[float][source]#
Return a series resampled to freq such that the volume is conserved.
The last step duration of the resampled series is set to the frequency
freq.- Parameters:
series (pd.Series) – A series of values of a volume-alike quantity with a DatetimeIndex. The sampling period can be constant or not (in this case, use
last_step_durationargument).freq (str | pd.Timedelta) – the freq to which the series is resampled. Must be a valid pandas frequency.
origin ({None, 'floor, 'ceil', pd.Timestamp}, optional) – What origin should be used for the target resampling range. See
index_to_freqfor details.last_step_duration (float, optional) – Duration of the last time-step in the
seriesin (s). The default isNonein which case the duration of the former-last time-step is used. Seeindex_to_freqfor details.
- Returns:
pd.Series – The resampled series.
See also
volume_conservativewhich resamples the flow-rate on the target instants.flow_rate_to_freqwhich resamples the volume on the giver frequency.