Skip to content

fix: preserve mode in extract_subseries and handle all-NaN series in strip - #3285

Open
shyamsharmas124-commits wants to merge 1 commit into
unit8co:masterfrom
shyamsharmas124-commits:fix/missing-values-strip-mode
Open

shyamsharmas124-commits wants to merge 1 commit into
unit8co:masterfrom
shyamsharmas124-commits:fix/missing-values-strip-mode

Conversation

@shyamsharmas124-commits

Copy link
Copy Markdown
Contributor

Summary

This PR addresses two interconnected edge cases in TimeSeries.strip(), TimeSeries.longest_contiguous_slice(), and extract_subseries():

  1. extract_subseries() crashed on boundary NaNs with mode="any":

    • In darts/utils/missing_values.py, series.strip() was called with default how="all" instead of how=mode. When mode="any" on a multivariate series with partial NaNs at the start or end, those rows were left unstripped.
    • series.gaps(mode=mode) then detected boundary gaps starting at index 0 or ending at index -1, resulting in end_times = gap_start - freq (outside the series start) and crashing with ValueError: Timestamp must be between ... or ValueError: The index corresponding to the provided point (-1) should be a valid index in series.
    • Now passes how=mode to series.strip(how=mode) and returns [] immediately if len(series) == 0.
  2. TimeSeries.strip() failed on all-NaN and empty series:

    • In _finite_rows_boundaries(), finite_rows.argmax() returns 0 on an all-False boolean array. For an all-NaN series (or under how="any" when all rows have at least one NaN), strip() returned the entire series of NaNs untouched instead of stripping them. On empty series, argmax() threw ValueError: attempt to get argmax of an empty sequence.
    • Now checks if not finite_rows.any(): return None, None and TimeSeries.strip() returns self[:0].
  3. TimeSeries.longest_contiguous_slice() boundary NaNs:

    • Now calls self.strip(how=mode) and returns stripped_series immediately if len(stripped_series) == 0.

Changes Made

  • darts/timeseries.py:
    • _finite_rows_boundaries(): Return None, None if not finite_rows.any().
    • TimeSeries.strip(): Return self[:0] if first_finite_row is None.
    • TimeSeries.longest_contiguous_slice(): Pass how=mode to self.strip(how=mode) and check for empty stripped series.
  • darts/utils/missing_values.py:
    • extract_subseries(): Pass how=mode to series.strip(how=mode) and return [] if len(series) == 0.
  • darts/tests/:
    • Added unit tests in test_timeseries_multivariate.py, test_timeseries.py, and test_utils.py covering all-NaN series, empty series, and multivariate partial-NaN boundaries.
  • CHANGELOG.md:
    • Added entry under [Unreleased] -> **Fixed**.

Verification

All 250 unit tests across test_timeseries_multivariate.py, test_utils.py, test_missing_values.py, and test_longest_contiguous_slice pass cleanly with zero linting/formatting errors (ruff check and ruff format).

@codecov

codecov Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.13%. Comparing base (555c8d1) to head (e7f0a53).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3285   +/-   ##
=======================================
  Coverage   97.13%   97.13%           
=======================================
  Files         175      175           
  Lines       19408    19416    +8     
=======================================
+ Hits        18851    18859    +8     
  Misses        557      557           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…strip

- In _finite_rows_boundaries, return None, None if not finite_rows.any()

- In TimeSeries.strip, return empty series self[:0] when no finite rows exist

- In TimeSeries.longest_contiguous_slice, pass how=mode to self.strip and handle empty stripped series

- In extract_subseries, pass how=mode to series.strip and return [] when series is empty

- Add unit tests across test_timeseries_multivariate.py, test_timeseries.py, and test_utils.py

- Update CHANGELOG.md under Unreleased

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant