You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
stats: length, null_count, min and max are computed on a 50,000-row sample above 1M cells #1050
DfStatsV2.get_operating_df and PlDfStatsV2.get_operating_df run every stat on df.sample(min(50_000, rows)) once rows * cols exceeds FAST_SUMMARY_WHEN_GREATER = 1_000_000 (buckaroo/pluggable_analysis_framework/df_stats_v2.py:62, :92; utils.py:9). That includes length, null_count, min and max, which a sample cannot answer. For a frame over 1M cells with more than 50,000 rows, length reads 50,000, null_count is the count inside the sample, and min and max are wrong in every column whose extreme row is not sampled. A frame over 1M cells with 50,000 rows or fewer is sampled as a full shuffled copy and stays exact. Nothing on the wire says the numbers describe a sample.
On pandas the planted -5 is missed in this run because the sample is unseeded, so the figure varies from run to run. Polars seeds it (seed=42) and happened to include that row.
Impact
length and the pinned min, max and null_count rows are wrong for most frames above about 1M cells and 50,000 rows, with no marker that they are sampled. Column width and the color_map rule read min and max.
Suggested fix
Compute length, null_count, min and max on the frame the stats class receives, and use the sample only for stats that need one (value_counts, mode, median, histogram). On /load that frame is already pre_limit-sampled (1,000,000 rows for the pandas and server samplers), so these stats are exact up to pre_limit. This changes visible numbers, so it needs a decision. A tier mechanism that does this and also lets a host cap the expensive stats by size is the direction in #911 and the stats ADR work (#1044).
Context
Found while sizing which stats to run on large frames. Reproduced on main at 992fdb3. Related: #911.
Repro script, run with uv run python repro_1050.py on main (992fdb3). The frame is 200,000 rows by 10 columns (2,000,000 cells), with a minimum of -5 at row 100 and a maximum of 2,000,000,000 at row 150,000 in every column.
RESULT pandas cells 2000000 length 50000 min 10797 max 999984288 null_count 0 | true min -5 true max 2000000000
RESULT polars cells 2000000 length 50000 min -5 max 999972934 null_count 0 | true min -5 true max 2000000000
length is 50,000 on both backends and max is wrong on both. Pandas min is wrong too. Polars min is right in this run. The polars sampler is seeded (seed=42, df_stats_v2.py:92) and the pandas one is not (:62), so the pandas values differ from run to run.
Activity
paddymul commentedon Oct 6, 2026
Repro script, run with
uv run python repro_1050.pyon main (992fdb3). The frame is 200,000 rows by 10 columns (2,000,000 cells), with a minimum of -5 at row 100 and a maximum of 2,000,000,000 at row 150,000 in every column.Output:
lengthis 50,000 on both backends andmaxis wrong on both. Pandasminis wrong too. Polarsminis right in this run. The polars sampler is seeded (seed=42,df_stats_v2.py:92) and the pandas one is not (:62), so the pandas values differ from run to run.docs(adr): ADR-001 cross-references to ADR-002 and ADR-003, and the p…
docs(adr): ADR-003 cites #1048, #1049 and #1050, records closed PRs, …