Skip to content

Feature/point in time series string support - #78

Draft
adefabian wants to merge 4 commits into
mainfrom
feature/point_in_time_series_string_support
Draft

Feature/point in time series string support#78
adefabian wants to merge 4 commits into
mainfrom
feature/point_in_time_series_string_support

Conversation

@adefabian

Copy link
Copy Markdown
Collaborator

Summary

Adds string-value support to PointsInTimeSeries. Previously values were always
coerced to np.float64, so string values raised on construction. String-valued
series now support the operations that make sense for them — sampling and equality
— while numeric-only operations fail loudly instead of silently corrupting data.

Changes

  • Type-aware construction: values whose dtype kind is U/S/O are stored as
    object; everything else stays float64. Timestamps remain float64. Empty
    series default to numeric (backward-compatible).
  • @_numeric_only guard: a decorator rejects numeric-only operations on
    string series with a clear TypeError. Applied to arithmetic (+ - * /),
    ordering (> >= < <=), and reductions (sum/mean/min/max). This blocks
    the cases numpy would silently mis-handle for strings (+ concatenates,
    * repeats, sum concatenates), not just the ones that already raise.
  • Allowed for strings: == / !=, synchronized / sampling, count, len.
  • Serialization: dtype() / get_data() are value-type aware — string series
    serialize as array<struct<tstart:double,value:string>> (a nested array can't
    hold mixed types), built as explicit [float(t), str(v)] pairs. Numeric path
    unchanged.

Test Plan

  • Unit tests added/updated
  • Manual testing completed
  • Documentation updated (if applicable)

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • No new linter warnings introduced

@codecov

codecov Bot commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.78%. Comparing base (83838ee) to head (4e60ac4).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #78      +/-   ##
==========================================
+ Coverage   88.69%   88.78%   +0.08%     
==========================================
  Files          60       60              
  Lines        5015     5046      +31     
  Branches      598      602       +4     
==========================================
+ Hits         4448     4480      +32     
+ Misses        461      460       -1     
  Partials      106      106              
Flag Coverage Δ
query_engine 84.77% <100.00%> (+0.19%) ⬆️
reporting 94.21% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...query_engine/model/series/points_in_time_series.py 93.12% <100.00%> (+1.98%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@adefabian
adefabian requested a review from tombonfert August 12, 2026 13:44

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason to change this file in this PR?

return PointsInTimeSeries(s0.tstarts, operation(s1.values, s0.values))
return PointsInTimeSeries(self.tstarts, operation(other, self.values))

@_numeric_only

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is cool! 👍


def test_empty_series_defaults_to_numeric():
# No observed value type -> numeric (backward-compatible default).
assert PointsInTimeSeries.empty()._is_string is False

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will introduce a problem in the method where we determine the return schema of the pandas UDF in the solver. We walk through the AST of every selected time series expression and evaluate with an empty cache. We build empty series objects and eventually derive the expected return type by calling the dtype method.

We need to extend the constructor of PointsInTimeSeries and make it explicit during init of the object whether the underlying data is of string or numerical type. Would this work in combination with the extension of TimeSeriesSelector, which will create the PointsInTimeSeries objects? I recommend to merge this PR with the one where you are extending TimeSeriesSelector.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I've seen your implementation in PR #79 regarding this topic. Lets merge the feature branch of this PR #78 into feature branch of PR #79 and close this one. Thanks! :)

@tombonfert tombonfert left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see comments

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.

2 participants