Skip to content

Commit 33c05d1

Browse files
committed
Expose fill_value option in moving window's window method
The `fill_value` option imputes missing values `NaN` or `None` in the moving window with the corresponding value. If `None` is passed, no imputation is done. By default, missing values are imputed with `NaN`. This prevents returning outdated return values accidentally. If missing values should be filled, the force_copy argument has to be true to avoid overwriting the underlying data. Signed-off-by: cwasicki <[email protected]>
1 parent bbab00f commit 33c05d1

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
- In `OrderedRingBuffer` and `MovingWindow`:
2929
- Support for integer indices is added.
3030
- Add `count_covered` method to count the number of elements covered by the used time range.
31+
- Add `fill_value` option to window method to impute missing values. By default missing values are imputed with `NaN`.
3132
- Add `at` method to `MovingWindow` to access a single element and use it in `__getitem__` magic to fully support single element access.
3233

3334

src/frequenz/sdk/timeseries/_moving_window.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ def window(
289289
end: datetime | int | None,
290290
*,
291291
force_copy: bool = True,
292+
fill_value: float | None = np.nan,
292293
) -> ArrayLike:
293294
"""
294295
Return an array containing the samples in the given time interval.
@@ -305,11 +306,16 @@ def window(
305306
force_copy: If `True`, the returned array is a copy of the underlying
306307
data. Otherwise, if possible, a view of the underlying data is
307308
returned.
309+
fill_value: If not None, will use this value to fill missing values.
310+
If missing values should be set, force_copy must be True.
311+
Defaults to NaN to avoid returning outdated data unexpectedly.
308312
309313
Returns:
310314
An array containing the samples in the given time interval.
311315
"""
312-
return self._buffer.window(start, end, force_copy=force_copy)
316+
return self._buffer.window(
317+
start, end, force_copy=force_copy, fill_value=fill_value
318+
)
313319

314320
async def _run_impl(self) -> None:
315321
"""Awaits samples from the receiver and updates the underlying ring buffer.

tests/timeseries/test_moving_window.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,16 @@ def test_eq(expected: list[float], start: int | None, end: int | None) -> None:
163163
sender, [3.0], start_ts=UNIX_EPOCH + timedelta(seconds=3)
164164
)
165165
test_eq([0.0, 1.0], 0, 2)
166-
# gap fill not supported yet:
167-
# test_eq([0.0, 1.0, np.nan, 3.0], 0, None)
168-
# test_eq([0.0, 1.0, np.nan, 3.0], -9, None)
169-
# test_eq([np.nan, 3.0], -2, None)
166+
# test gaps to be NaN
167+
test_eq([0.0, 1.0, np.nan, 3.0], 0, None)
168+
test_eq([np.nan, 3.0], -2, None)
169+
170+
# Test fill_value
171+
assert np.allclose(
172+
np.array([0.0, 1.0, 2.0, 3.0]),
173+
window.window(0, None, fill_value=2.0),
174+
equal_nan=True,
175+
)
170176

171177
# Complete window
172178
await push_logical_meter_data(sender, [0.0, 1.0, 2.0, 3.0, 4.0])

0 commit comments

Comments
 (0)