Repository navigation
fix: reject nulls in id and time columns in validate_format - #322
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Approval recommended
The focused checks run before the target-column early return, with regression coverage for both dataframe backends and no unresolved findings.
No open issues 🎉
What changed in this PR
This PR adds early rejection of null identifiers and timestamps to shared dataframe validation, preventing downstream processing errors and incorrect results.
Changes:
- Reject null id and time values in pandas and polars, including when
target_col=None. - Add validation tests across supported column types and null representations.
- Add a
process_dfregression test for null identifiers in both backends.
| File | Description |
|---|---|
| utilsforecast/validation.py | Adds backend-specific null detection and id/time validation. |
| tests/test_validation.py | Tests null rejection with and without target validation. |
| tests/test_processing.py | Verifies process_df rejects null identifiers early. |
Review effort: Balanced
| def _has_nulls(s: Series) -> bool: | ||
| if isinstance(s, pd.Series): | ||
| return s.hasnans | ||
| return s.null_count() > 0 |
There was a problem hiding this comment.
null_count() doesn't count NaN in polars, so a float id column with NaN passes here while the pandas branch (hasnans) rejects it:
validate_format(pl.DataFrame({'unique_id': [1.0, float('nan')], 'ds': [1, 2], 'y': [1., 2.]})) # no errorThose ids then reach process_df/fill_gaps and get misgrouped. Something like s.null_count() > 0 or (s.dtype.is_float() and s.is_nan().any()) would match pandas. Adding pl.Series([1.0, float('nan')]) to test_validate_format_null_ids would cover it.
There was a problem hiding this comment.
NaNs get grouped together in polars
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What
validate_formatnow raises aValueErrorwhen the id or time column contains null values (None, NaN, NaT or NA in pandas; nulls in polars). The check runs even whentarget_col=None.Why
Null ids and times aren't supported, but nothing rejected them, so they either failed far from the cause or produced wrong results. For example, polars
process_dfwith ids['a', 'a', None, 'b']silently returned anindptrthat gave the null series a row from'a'and'a'the null row, while pandas raisedTypeError: '<=' not supported between instances of 'str' and 'NoneType'. Sinceprocess_df,fill_gaps,pipeline,rectifyandplot_seriesall callvalidate_format, they now fail early with a clear message.🤖 Generated with Claude Code