feat(diff-stats): xorq diff analysis klasses — pinned-row stats + styling for keyed-diff frames - #959
feat(diff-stats): xorq diff analysis klasses — pinned-row stats + styling for keyed-diff frames#959paddymul wants to merge 1 commit into
Conversation
Red per TDD for the diff analysis klasses proven in the tallyman
diff-view prototypes: three pinned-row summary stats over keyed-diff
frames ({col} / {col}_v2 / {col}_pct_delta triples) plus the styling
klass that assembles the diff view.
- diff_histogram: change distribution in log2-ratio space, 11 bins with
an edge pinned at zero change
- diff_line: new/old as a percent (100 = unchanged), in key order
- left_right: before (lineGray) and after (lineRed) series on one chart
so both share a scale
- all three resample to <= 100 points by position-bucketed means and
return [] on non-diff columns
- DiffStyling: hides helper columns, renames _v2 to the bare metric,
paints via color_from_column from {col}_cellcolor, old value on
hover; inert on frames without _cellcolor columns
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: aff733059d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| from buckaroo.customizations.xorq_diff_stats import ( # noqa: E402 | ||
| DIFF_HISTOGRAM_LABELS, | ||
| XORQ_DIFF_STATS, | ||
| DiffStyling) |
There was a problem hiding this comment.
Add the diff stats module before importing it
In xorq-enabled test environments this import is executed, but this commit only adds the test file and does not add buckaroo/customizations/xorq_diff_stats.py; git ls-tree for the reviewed commit shows no such module. As a result pytest collection raises ModuleNotFoundError before any of these tests can run, so the xorq unit suite is broken until the implementation is included or the tests are gated differently.
Useful? React with 👍 / 👎.
Ports the diff analysis klasses proven as tallyman project artifacts into buckaroo proper. Companion to #958 (which carries the renderer changes: per-bar histogram colors, sparkline rendering); this PR is the analyses themselves and depends only on displayers that already exist.
What
A new
buckaroo/customizations/xorq_diff_stats.pywith three phase-2 summary stats over keyed-diff frames — tables carrying{col}/{col}_v2/{col}_pct_deltatriples — plus the styling klass that assembles the view:diff_histogram— the per-column change distribution in log2-ratio space, 11 bins with an edge pinned at exactly zero change. A column where everything shrank reads as all mass left of zero at a glance.diff_line— new/old as a percent (100 = unchanged), one point per row in key order.left_right— the before series (lineGray) and after series (lineRed) on one chart per column, raw units, so both share a scale and a collapsed after-series reads as exactly that.floor(row_number × min(100, n) / n)), so they stay readable at any row count; at ≤ 100 rows this degenerates to one point per row. On columns that are not the_v2side of a triple they return[]without issuing a query.DiffStyling— hides the helper columns (_pct_delta,_abs_delta,_eq,membership, the old-value column), renames_v2to the bare metric, paints cells viacolor_from_columnfrom a precomputed{col}_cellcolorcolumn, shows the old value on hover, and pins the three stats. Inert on frames without_cellcolorcolumns, so it can safely serve as amainoverride.Unlike the tallyman prototypes (sandboxed
compute(col)stats that had to reach sibling columns throughcol.op().reland smuggle results out as array-of-struct scalar subqueries), these use the phase-2XorqExpr+XorqExecuteidiom the built-inhistogramalready uses — own query, post-processed in Python.Why
A diff view's cells can only color one number at a time. The summary rows carry the rest of the story: the shape of the change distribution, and the before/after trajectories on a shared scale. Prototyped and validated against real diffs (NYC taxi by-hour, 24 rows, and a 1440-row synthetic) in tallyman.
Not wired into
XORQ_STATS_V2defaults — exported asXORQ_DIFF_STATSfor consumers to opt in viaextra_klasses, the same path project-authored stats use.Tests
TDD structure: this PR's first commit carries only the failing tests (red on the missing module); the implementation lands in the follow-up commit.
tests/unit/test_xorq_diff_stats.py— bin labels and zero-edge semantics, all-decrease mass lands left of zero, per-row points under the cap, exact-100-point resampling with bucket-mean values,[]on non-diff columns, log-safety atpct_delta == -1, andDiffStylinghide/rename/color/tooltip behavior plus inertness without_cellcolor.Column-naming note:
compare.col_join_dfsuses the|df2suffix convention; these stats use the_v2/_pct_deltaconvention of the keyed-diff builder they were proven against. Unifying the two shapes is deliberate follow-up.🤖 Generated with Claude Code