Repository navigation
fix(histogram): a float column holding an infinity keeps a numeric histogram in xorq, pandas and polars (#1055) - #1069
Merged
Merged
Conversation
…1055) One inf makes max - min infinite, every bucket NaN, and the int64 cast fails; histogram's default=[] hides the error and histogram_bins comes back as [nan, inf, inf, ...]. Covers +inf, -inf and both, for histogram and histogram_bins. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
) When a float column's min or max is infinite, _numeric_histogram and histogram_bins now look up the min and max of the finite values with one small query and bucket over that range. The infinite rows are filtered out of the bucket query, so the population sums to 100% of the finite values. min and max still report the infinities. A column with no finite values, or only one, still gets no histogram. histogram_bins takes expr, execute and orig_col_name for that query, so it is now a query stat. Columns with a finite range run no extra query. df_with_infinity no longer fails the warm-load check in test_stat_cache.py (the #1057 xfail was strict), so its entry comes out of _DDD_KNOWN_FAILURES. #1057 still applies to pl_df_with_temporal_edges. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Contributor
📦 TestPyPI package publishedpip install --index-strategy unsafe-best-match --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo==0.15.9.dev37516214008or with uv: uv pip install --index-strategy unsafe-best-match --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo==0.15.9.dev37516214008MCP server for Claude Codeclaude mcp add buckaroo-table -- uvx --from "buckaroo[mcp]==0.15.9.dev37516214008" --index-strategy unsafe-best-match --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo-table📖 Docs preview🎨 Storybook preview |
paddymul
marked this pull request as ready for review
October 6, 2026 18:13
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…istogram in pandas and polars (#1072) The pandas and polars histogram takes its 1% and 99% tails with np.quantile / Series.quantile over the raw column. With an infinity in it, numpy's interpolation can return NaN (inf - inf, or inf * 0), the meat comes out empty, and the column drops to the categorical histogram with no histogram_bins. Where the quantile is inf instead, the tail labels read 'infT'. Which one depends on where 0.99 * (n - 1) falls beside the infinity, e.g. NaN at 50 and 101 non-null values with one +inf, inf at 99 and 100. Tests, for pandas and polars: - a sweep over 5 infinity shapes x 12 finite-value counts (and, for polars, alone / beside a NaN / beside a null): the histogram is numeric, histogram_bins is 11 finite edges, and the finite buckets equal those of the column without the infinities - every DDD float column that holds an infinity beside more than 5 distinct finite values, picked up automatically from ddd_library - pandas float64, float32 and nullable Float64 - tail buckets name the infinity ('-inf...', '...-inf'), and fmt_tail_bucket formats infinite bounds as 'inf' New DDD frames, df_with_infinities_among_values and its polars counterpart: 101-row float columns where np.quantile is NaN, plus a control without infinities. They also run through test_stat_cache's warm-load checks. Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
paddymul
enabled auto-merge
October 6, 2026 18:47
… infinity (pandas, polars) histogram_series and pl_histogram_series took the 1% and 99% tails over the raw column. With an infinity in it np.quantile can return NaN (inf - inf inside its interpolation), which emptied the middle and dropped the column to the categorical histogram; where it returned inf instead, the finite buckets stretched to the maximum and the tail read 'infT'. Tails are now taken over the finite values. The infinities fall outside them, so they land in the tail buckets, and the buckets of the finite values are the same with or without them. A column with no finite values still gets the categorical histogram. Integer and Decimal columns take the same path as before (polars guards on float dtypes). fmt_num returns 'inf', '-inf' or 'nan' for a non-finite bound instead of running it through the SI-prefix branch, so a tail reads '198–inf' and '-inf<>1.5'. Also adds guards that pass without the fix: columns with nothing to bucket (only infinities, a constant beside an infinity), polars Float32, and the DDD-driven check for xorq. The two new DDD frames are added to the docs DDD page. #1072 was merged into this branch with only its test commit (b0c69d3); this is its fix commit, cherry-picked from 374333a. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 6, 2026
pandas stats: a nullable Float64/Int64 column loses mean, median and std when its std is pd.NA
#1074
Open
This was referenced Oct 6, 2026
Open
Open
Open
This was referenced Oct 6, 2026
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR fixes the xorq side (#1055) and, since #1072 was merged into this branch, the pandas and polars side. #1072 went in with only its test commit (b0c69d3); its fix commit is ac5a0cd here.
Problem
xorq:
_numeric_histograminxorq_stats_v2.pybuckets with(x - min) / (max - min) * 10cast to int64. A float column holdinginfor-infmakesmax - mininfinite, so that row's bucket is NaN and the query fails withCan't cast value NaN to type Int64.histogram'sdefault=[]swallows the error (#687), so the column shows no histogram.histogram_binscomputes[nan, inf, inf, ...]from the same infinite range.pandas and polars:
histogram_seriesandpl_histogram_seriestake the 1% and 99% tails withnp.quantile/Series.quantileover the raw column, then histogram the values between them. With an infinity in the column, numpy's interpolation can return NaN (inf - inf, orinf * 0, insidenp.quantile). Every comparison against a NaN tail is False, so the middle is empty,histogram_argscomes back empty, and the column falls to the categorical histogram (top value counts) with nohistogram_bins, socolor_maphas nothing to read. Where the quantile isinfinstead, the middle includes every finite value, the finite buckets stretch to the maximum, and the tail label readsinfT–infT. Which one happens depends on where0.99 * (n - 1)falls beside the infinity: with a single+inf, the quantile is NaN at 50 and 101 non-null values andinfat 99 and 100.Change
xorq: when a float column's min or max is infinite,
_numeric_histogramandhistogram_binscall_finite_range, which runs one query for the min and max of the column's finite values. The histogram's bucket query drops the infinite rows, so the populations sum to 100% of the finite values, andhistogram_binsspans the finite range.minandmaxstill report the infinities. A column with no finite values, or one, still gets no histogram. A column with a finite range runs no extra query. The issue allowed either leaving the infinities out of the buckets or counting them in the end buckets. I left them out: an end bucket that includesinfwould be labelled with a finite range it doesn't cover.histogram_binsnow takesexpr,executeandorig_col_namefor that query, so the pipeline treats it as a query stat (_is_query_func) and caches its cell the way it cacheshistogram's.pandas and polars: both functions take the tails over the finite values. The infinities fall outside them and land in the tail buckets, and the buckets of the finite values are the same with or without the infinities. The polars filter applies to float dtypes only, so integer and Decimal columns take the path they did before. A numeric column with 5 or fewer distinct values is still categorical (an infinity counts as a distinct value), and a column with no finite values still gets the categorical histogram.
fmt_numreturnsinf,-infornanfor a non-finite bound, so a tail reads198–infand-inf<>1.5instead ofinfT.df_with_infinityno longer fails the warm-load check intest_stat_cache.py: the strict #1057 xfail on it XPASSed, so its entry comes out of_DDD_KNOWN_FAILURES, as that table's comment says to do. #1057 still applies topl_df_with_temporal_edges.New DDD frames:
df_with_infinities_among_valuesandpl_df_with_infinities_among_values(101-row float columns wherenp.quantileis NaN, plus a control without infinities; the polars frame adds a real NaN and a null). They are on the docs DDD page, andtest_stat_cache.pypicks them up automatically.Tests
xorq,
TestHistogramintests/unit/test_xorq_stats_v2.py, each for+inf,-infand both: the histogram is non-empty and sums to 100% withmin/maxstill reporting the infinities, andhistogram_binshas 11 finite edges spanning the finite values. These failed on CI before the xorq fix (run 37506145362, Python / Test (Max Versions) (3.13): 6 failed, 1508 passed).pandas (
tests/unit/histogram_test.py) and polars (TestPlHistogramintests/unit/test_pl_stats_v2.py):+inf,-inf, two-inf, both, 5 on each side) and 12 finite-value counts that straddle the NaN/inf boundary; polars also runs each alone, beside a NaN, and beside a null. Each asserts a numeric histogram (no categorical entries), 11 finitehistogram_bins, and the same finite buckets as the column without the infinitiesddd_float_columns_with_infinitiesintests/unit/test_utils.pyreads them fromddd_library, so frames added later are covered); the xorq test file runs the same columnsfmt_tail_bucketformats infinite bounds asinfThese failed on CI before the pandas/polars fix (run 37513631803 on #1072's branch, and run 37513943690 on this PR after #1072's test commit merged: Python / Test (3.14), 240 failed, 997 passed; all 240 are the new tests). The fix commit adds guards that pass either way: columns with nothing to bucket, polars Float32, and the xorq DDD check. Locally the full unit suite passes on this branch (1940 passed, 17 skipped, 15 xfailed).
Not in this PR
Found while checking; each is separate from these fixes:
Float64column holding an infinity raises inmean,medianandstd(pandas stats: a nullable Float64/Int64 column loses mean, median and std when its std is pd.NA #1074)_formatted_char_count(customizations/styling.py:25) guards NaN but not infinity, soint(max_abs)raisesOverflowErrorand the column's styling falls back to the parent class with a logged warning.df_with_infinitydoes this too. (styling: a float column holding an infinity falls back to the obj displayer (OverflowError in _formatted_char_count) #1075)[nan, ...]bin edges, becausemaxis NaN (xorq stats: a float column holding a NaN gets no histogram and all-NaN histogram_bins #1076)Closes #1055.
🤖 Generated with Claude Code