PolarsTable parity
Verification
Scope
Columns, types, groups, and rows from about 120 pipelines on PolarsTable, phibble's Polars backend. Compared with the same pipelines on DataFrame.
References
- Reference
- phplyr on phibble's DataFrame
- Versions
- PHP 8.5.10, phibble v0.8.0 (9e63ca5), php_polars 0.2.2
Data
- panel.csv
- 12 rows: id, g, year, value, score, label. Source
- schools.csv
- 250 rows: school, study_hours, prior_score, score. Source
- events.csv
- 5 rows: id, t, amount. Source
- periods.csv
- 5 rows: id, start, end, label. Source
- join_x.csv
- 5 rows: id, k, v. Source
- join_y.csv
- 5 rows: key, k, w. Source
- wide.csv
- 3 rows: id, name, wk1, wk2, wk3. Source
- long.csv
- 6 rows: id, key, val, w. Source
- who.csv
- 2 rows: country, new_sp_m014, new_sp_f014, new_ep_m65. Source
- strings.csv
- 4 rows: id, s, tags, code, n. Source
Method
tests/PolarsTest.php runs each pipeline on DataFrame and on PolarsTable and compares every value. Values compared is the number of assertions in a case; a case fails if any assertion fails.
- Check
- Comparison with a reference implementation
- Recorded
- 2026-11-02, PHP 8.5.10, macOS (arm64), commit 65e6a46
Tolerances
|x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1)
Applies to: Floating-point values
exact equality
Applies to: Column names, row counts and order, strings, integers, booleans, dates, and missing values
x: package value; r: reference value. Absolute error: |x − r|. Relative error: |x − r| / max(|r|, 1). Max errors are over the values a row compares.
Results
117 comparisons: 117 pass, 0 fail, 0 skipped.
All 117 comparisons
| Case | Quantity | Criterion | Values | Package value | Reference value | Max abs. error | Max rel. error | Status |
|---|---|---|---|---|---|---|---|---|
| filter expr | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 33 | 0 | 0 | pass | ||
| filter closure | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 61 | 0 | 0 | pass | ||
| filter grouped | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 47 | 0 | 0 | pass | ||
| filter_out | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 54 | 0 | 0 | pass | ||
| filter if_any | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 61 | 0 | 0 | pass | ||
| filter if_all | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 47 | 0 | 0 | pass | ||
| arrange | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 89 | 0 | 0 | pass | ||
| arrange by group | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 89 | 0 | 0 | pass | ||
| distinct | Values | exact equality | 32 | pass | ||||
| distinct keep all | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 26 | 0 | 0 | pass | ||
| slice | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 26 | 0 | 0 | pass | ||
| slice_head grouped | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 47 | 0 | 0 | pass | ||
| slice_tail | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 26 | 0 | 0 | pass | ||
| slice_min ties | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 40 | 0 | 0 | pass | ||
| slice_max prop | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 26 | 0 | 0 | pass | ||
| top_n | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 47 | 0 | 0 | pass | ||
| head | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 26 | 0 | 0 | pass | ||
| drop_na | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 75 | 0 | 0 | pass | ||
| select helpers | Values | exact equality | 53 | pass | ||||
| select where | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 65 | 0 | 0 | pass | ||
| select rename | Values | exact equality | 41 | pass | ||||
| rename | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 89 | 0 | 0 | pass | ||
| rename_with | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 89 | 0 | 0 | pass | ||
| relocate | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 89 | 0 | 0 | pass | ||
| mutate expr | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 113 | 0 | 0 | pass | ||
| mutate closure | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| mutate grouped | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 125 | 0 | 0 | pass | ||
| mutate keep used | Values | exact equality | 41 | pass | ||||
| mutate before | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| mutate by | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| transmute | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 41 | 0 | 0 | pass | ||
| if_else and case_when | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 113 | 0 | 0 | pass | ||
| coalesce na_if between | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 125 | 0 | 0 | pass | ||
| recode_values | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| windows | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 221 | 0 | 0 | pass | ||
| lag order_by | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| consecutive_id | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| across mutate | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 89 | 0 | 0 | pass | ||
| across helpers | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 137 | 0 | 0 | pass | ||
| str helpers | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 113 | 0 | 0 | pass | ||
| cur_group_id | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| summarise | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 29 | 4.4e-16 | 1.2e-16 | pass | ||
| summarise first last nth | Values | exact equality | 23 | pass | ||||
| summarise closure | Values | exact equality | 14 | pass | ||||
| summarise groups keep | Values | exact equality | 41 | pass | ||||
| summarise by | Values | exact equality | 41 | pass | ||||
| summarise across | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 77 | 2.8e-14 | 3.9e-16 | pass | ||
| summarise pick | Values | exact equality | 14 | pass | ||||
| reframe | Values | exact equality | 32 | pass | ||||
| count | Values | exact equality | 41 | pass | ||||
| count wt | Values | exact equality | 14 | pass | ||||
| tally | Values | exact equality | 14 | pass | ||||
| add_count | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| add_tally | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| rowwise | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| ungroup | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| group_modify | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 26 | 0 | 0 | pass | ||
| pull | Values | exact equality | 1 | pass | ||||
| add_row | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 26 | 4.5 | 4.5 | 0 | 0 | pass |
| big pipeline | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 77 | 5.3e-15 | 4.5e-16 | pass | ||
| pivot_longer | Values | exact equality | 35 | pass | ||||
| pivot_longer sep | Values | exact equality | 35 | pass | ||||
| pivot_longer slowest | Values | exact equality | 50 | pass | ||||
| pivot_wider | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 17 | 0 | 0 | pass | ||
| pivot_wider multi | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 23 | 0 | 0 | pass | ||
| pivot_wider values_fn | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 20 | 0 | 0 | pass | ||
| complete | Values | exact equality | 45 | pass | ||||
| expand nesting | Values | exact equality | 149 | pass | ||||
| fill | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 89 | 0 | 0 | pass | ||
| replace_na | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 89 | 0 | 0 | pass | ||
| uncount | Values | exact equality | 23 | pass | ||||
| unite | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 77 | 0 | 0 | pass | ||
| separate | Values | exact equality | 21 | pass | ||||
| separate_wider_delim | Values | exact equality | 25 | pass | ||||
| separate_longer_delim | Values | exact equality | 26 | pass | ||||
| separate_rows | Values | exact equality | 26 | pass | ||||
| extract | Values | exact equality | 21 | pass | ||||
| nest | Values | exact equality | 41 | pass | ||||
| group_nest sizes | Values | exact equality | 14 | pass | ||||
| unnest | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 89 | 0 | 0 | pass | ||
| cur_group | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| c_across | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| order_by | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| with_groups | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| recode | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 101 | 0 | 0 | pass | ||
| group_data | Values | exact equality | 14 | pass | ||||
| top_frac | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 26 | 0 | 0 | pass | ||
| pivot names_transform | Values | exact equality | 50 | pass | ||||
| pivot unused_fn | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 20 | 0 | 0 | pass | ||
| pivot id_expand | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 17 | 0 | 0 | pass | ||
| pivot specs | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 17 | 0 | 0 | pass | ||
| gather | Values | exact equality | 35 | pass | ||||
| spread | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 17 | 0 | 0 | pass | ||
| chop unchop | Values | exact equality | 53 | pass | ||||
| chop | Values | exact equality | 14 | pass | ||||
| pack unpack | Table values | |x − r| ≤ 1e-9 + 1e-9 × max(|r|, 1) | 89 | 0 | 0 | pass | ||
| unnest_wider | Values | exact equality | 77 | pass | ||||
| unnest_longer | Values | exact equality | 115 | pass | ||||
| hoist | Values | exact equality | 77 | pass | ||||
| Joins and binds: inner_join | Values | exact equality | 41 | pass | ||||
| Joins and binds: left_join suffix | Values | exact equality | 47 | pass | ||||
| Joins and binds: right_join | Values | exact equality | 35 | pass | ||||
| Joins and binds: full_join | Values | exact equality | 40 | pass | ||||
| Joins and binds: semi_join | Values | exact equality | 21 | pass | ||||
| Joins and binds: anti_join | Values | exact equality | 9 | pass | ||||
| Joins and binds: cross_join | Values | exact equality | 33 | pass | ||||
| Joins and binds: join_by inequality | Values | exact equality | 47 | pass | ||||
| Joins and binds: bind_rows | Values | exact equality | 75 | pass | ||||
| Joins and binds: bind_cols | Values | exact equality | 20 | pass | ||||
| Joins and binds: union | Values | exact equality | 17 | pass | ||||
| Joins and binds: union_all | Values | exact equality | 25 | pass | ||||
| Joins and binds: intersect | Values | exact equality | 13 | pass | ||||
| Joins and binds: setdiff | Values | exact equality | 7 | pass | ||||
| Joins and binds: symdiff | Values | exact equality | 9 | pass | ||||
| Joins and binds: rows_update | Values | exact equality | 25 | pass | ||||
| Joins and binds: rows_upsert | Values | exact equality | 23 | pass | ||||
| Runs rolling and overlap joins the same on PolarsTable | Values | exact equality | 66 | pass |
Reproduction
POLARS_PHP="php -d extension=/path/to/libphp_polars.so" bin/site-verifications
- Raw record
- site/verifications/polars.json