ISD: Iterative Shifting Disaggregation (https://doi.org/10.3390/s25030895)
Minimal, self-contained Python implementation of the Iterative Shifting Disaggregation (ISD) algorithm for multi-source, irregularly sampled, and overlapped time series.
This repo mirrors the algorithmic structure and helper functions described in the paper's Appendix and Section 3 (prediction and constrained shifting). It does not include any proprietary code.
- Naïve disaggregation for multiple low-frequency series to a common daily axis
- Design matrix construction for exogenous variables (HDD, CDD, HDDW, trend, Fourier terms)
- Iterative prediction with ordinary least squares
- Constrained, interval-wise load shifting that preserves coherence with the original intervals
- Simple example script and lightweight tests
pip install -e .
from isd import ISD, naive_disaggregate, aggregate_series, construct_design_matrix
import numpy as np
# toy inputs
A = [(4, 48), (9, 75)] # (end_day, value) with irregular interval lengths implied by differences in end_day
B = [(4, 88), (9, 110)]
C = [(4, 116), (9, 165)]
# build daily exogenous variables (here we just make placeholders)
ND = 9
Xcols = {
"bias": np.ones(ND),
"HDD65": np.linspace(10, 0, ND),
"CDD65": np.zeros(ND),
"HDDW65": np.linspace(8, 1, ND),
}
X = construct_design_matrix(Xcols)
a = naive_disaggregate(A) # length ND array
b = naive_disaggregate(B)
c = naive_disaggregate(C)
y0 = aggregate_series([a, b, c])
isd = ISD(n_lr_models=3, n_disagg_cycles=3, alpha=0.05)
y_hat = isd.fit_transform(y0, X, intervals=[A, B, C])
print(y_hat)
- Interval encoding: each low-frequency series is represented as a list of tuples
(end_day, value)
, where the number of days spanned by the current interval isend_day - prev_end_day
(withprev_end_day
starting at 0). - This keeps the code general and avoids storing explicit day ranges.
- Replace the placeholders with your weather and calendar variables to reproduce realistic behavior.