Loading the parity record
Fetching the measured run — the pinned upstream oracle, every symbol and every case.
Fetching the measured run — the pinned upstream oracle, every symbol and every case.
Parity / pandas
Every number on this page was produced by running both implementations over the same cases: the real pandas package pinned at 2.3.3 answers first, and its answer is the expectation the Go port is held to. Nothing is a hand-written expectation, so a new upstream release re-scores the port on its own. See pandas for the port's own documentation. Source: github.com/malcolmston/pandas.
Not a generic diagram: every node below names an artefact of this harness — the pinned package it installed, the runner files it started, the case files it streamed, and the counts it wrote out.
| Case group | Cases | Match | Mismatch | Group parity |
|---|---|---|---|---|
| stats | 71 | 61 | 10 | 85.9% |
| mutate | 32 | 30 | 2 | 93.8% |
| construct | 26 | 22 | 4 | 84.6% |
| selection | 26 | 24 | 2 | 92.3% |
| groupby | 20 | 12 | 7 | 60.0% |
| csv | 17 | 7 | 10 | 41.2% |
| missing | 13 | 11 | 2 | 84.6% |
| merge | 12 | 7 | 5 | 58.3% |
Every exported symbol of the upstream package, and what the port offers for it. The upstream list is derived mechanically, never from a README: import pandas as pd
from pandas.core.groupby import DataFrameGroupBy
[n for n in dir(pd.DataFrame) if not n.startswith("_")] # 209
[n for n in dir(pd.Series) if not n.startswith("_")] # 210
[n for n in dir(pd.Series.str) if not n.startswith("_")] # 56
[n for n in dir(DataFrameGroupBy) if not n.startswith("_")] # 66
[n for n in dir(pd) if not n.startswith("_")] # module level. A symbol with no case is untested, never a match.
| Upstream symbol | Go symbol | Status | Cases | Note |
|---|---|---|---|---|
| pandas.DataFrame.T | DataFrame.Transpose | untested | — | |
| pandas.DataFrame.abs | DataFrame.Abs | match | frame-abs | |
| pandas.DataFrame.add | — | missing | — | |
| pandas.DataFrame.add_prefix | — | missing | — | |
| pandas.DataFrame.add_suffix | — | missing | — | |
| pandas.DataFrame.agg | — | missing | — | |
| pandas.DataFrame.aggregate | — | missing | — | |
| pandas.DataFrame.align | — | missing | — | |
| pandas.DataFrame.all | — | missing | — | |
| pandas.DataFrame.any | — | missing | — | |
| pandas.DataFrame.apply | — | missing | — | |
| pandas.DataFrame.applymap | — | missing | — | |
| pandas.DataFrame.asfreq | — | missing | — | |
| pandas.DataFrame.asof | — | missing | — | |
| pandas.DataFrame.assign | DataFrame.WithColumn | match | with-column-bad-length, with-column-new-float, with-column-new-string, with-column-replace | |
| pandas.DataFrame.astype | — | missing | — | |
| pandas.DataFrame.at | — | missing | — | |
| pandas.DataFrame.at_time | — | missing | — | |
| pandas.DataFrame.attrs | — | missing | — | |
| pandas.DataFrame.axes | — | missing | — | |
| pandas.DataFrame.backfill | — | missing | — | |
| pandas.DataFrame.between_time | — | missing | — | |
| pandas.DataFrame.bfill | — | missing | — | |
| pandas.DataFrame.bool | — | missing | — | |
| pandas.DataFrame.boxplot | — | missing | — | |
| pandas.DataFrame.clip | — | missing | — | |
| pandas.DataFrame.columns | DataFrame.Names | match | frame-names-sales | |
| pandas.DataFrame.combine | — | missing | — | |
| pandas.DataFrame.combine_first | — | missing | — | |
| pandas.DataFrame.compare | — | missing | — | |
| pandas.DataFrame.convert_dtypes | — | missing | — | |
| pandas.DataFrame.copy | DataFrame.Copy | untested | — | |
| pandas.DataFrame.corr | DataFrame.Corr | match | corr-matrix | |
| pandas.DataFrame.corrwith | — | missing | — | |
| pandas.DataFrame.count | — | missing | — | |
| pandas.DataFrame.cov | — | missing | — | |
| pandas.DataFrame.cummax | — | missing | — | |
| pandas.DataFrame.cummin | — | missing | — | |
| pandas.DataFrame.cumprod | — | missing | — | |
| pandas.DataFrame.cumsum | — | missing | — | |
| pandas.DataFrame.describe | DataFrame.Describe | differs | describe-nums, describe-sales, describe-strings-only | |
| pandas.DataFrame.diff | — | missing | — | |
| pandas.DataFrame.div | — | missing | — | |
| pandas.DataFrame.divide | — | missing | — | |
| pandas.DataFrame.dot | — | missing | — | |
| pandas.DataFrame.drop | DataFrame.Drop | differs | drop-one, drop-two, drop-unknown | |
| pandas.DataFrame.drop_duplicates | DataFrame.DropDuplicates | match | drop-duplicates | |
| pandas.DataFrame.droplevel | — | missing | — | |
| pandas.DataFrame.dropna | DataFrame.DropNA | match | dropna-gaps, dropna-nothing-missing, dropna-sales | |
| pandas.DataFrame.dtypes | Series.DType | match | frame-dtypes-nums, frame-dtypes-sales | |
| pandas.DataFrame.duplicated | — | missing | — | |
| pandas.DataFrame.empty | — | missing | — | |
| pandas.DataFrame.eq | — | missing | — | |
| pandas.DataFrame.equals | — | missing | — | |
| pandas.DataFrame.eval | — | missing | — | |
| pandas.DataFrame.ewm | — | missing | — | |
| pandas.DataFrame.expanding | — | missing | — | |
| pandas.DataFrame.explode | — | missing | — | |
| pandas.DataFrame.ffill | — | missing | — | |
| pandas.DataFrame.fillna | DataFrame.FillNA | differs | fillna-all-columns-zero, fillna-bool-column, fillna-float-into-int-column, fillna-one-column-float, fillna-one-column-int, fillna-unknown-column | |
| pandas.DataFrame.filter | — | missing | — | |
| pandas.DataFrame.first | — | missing | — | |
| pandas.DataFrame.first_valid_index | — | missing | — | |
| pandas.DataFrame.flags | — | missing | — | |
| pandas.DataFrame.floordiv | — | missing | — | |
| pandas.DataFrame.from_dict | FromMap | untested | — | |
| pandas.DataFrame.from_records | FromRecords | untested | — | |
| pandas.DataFrame.ge | — | missing | — | |
| pandas.DataFrame.get | — | missing | — | |
| pandas.DataFrame.groupby | DataFrame.GroupBy | match | gb-groups-count, gb-groups-two-keys, gb-unknown-key | |
| pandas.DataFrame.gt | — | missing | — | |
| pandas.DataFrame.head | DataFrame.Head | match | head-3, head-over, head-zero | |
| pandas.DataFrame.hist | — | missing | — | |
| pandas.DataFrame.iat | — | missing | — | |
| pandas.DataFrame.idxmax | — | missing | — | |
| pandas.DataFrame.idxmin | — | missing | — | |
| pandas.DataFrame.iloc | DataFrame.ILoc | match | iloc-clamped-high, iloc-empty-range, iloc-from-zero, iloc-middle | |
| pandas.DataFrame.index | DataFrame.Index | match | frame-index-sales | |
| pandas.DataFrame.infer_objects | — | missing | — | |
| pandas.DataFrame.info | — | missing | — | |
| pandas.DataFrame.insert | — | missing | — | |
| pandas.DataFrame.interpolate | — | missing | — | |
| pandas.DataFrame.isetitem | — | missing | — | |
| pandas.DataFrame.isin | — | missing | — | |
| pandas.DataFrame.isna | — | missing | — | |
| pandas.DataFrame.isnull | — | missing | — | |
| pandas.DataFrame.items | — | missing | — | |
| pandas.DataFrame.iterrows | — | missing | — | |
| pandas.DataFrame.itertuples | — | missing | — | |
| pandas.DataFrame.join | — | missing | — | |
| pandas.DataFrame.keys | — | missing | — | |
| pandas.DataFrame.kurt | — | missing | — | |
| pandas.DataFrame.kurtosis | — | missing | — | |
| pandas.DataFrame.last | — | missing | — | |
| pandas.DataFrame.last_valid_index | — | missing | — | |
| pandas.DataFrame.le | — | missing | — | |
| pandas.DataFrame.loc | DataFrame.Loc | differs | loc-int-labels, loc-missing-label, loc-reordered-labels, loc-string-index, loc-untyped-int-label | |
| pandas.DataFrame.lt | — | missing | — | |
| pandas.DataFrame.map | — | missing | — | |
| pandas.DataFrame.mask | — | missing | — |
Every case the harness streamed to both runners, with the exact upstream symbol and Go symbol it exercised. A deliberate, documented difference is a deviation and is counted apart from a mismatch.
| Case | Group | Upstream symbol | Go symbol | Status | Note |
|---|---|---|---|---|---|
| series-float64 | construct | pandas.Series | pandas.NewSeriesTyped | match | |
| series-int64 | construct | pandas.Series | pandas.NewSeriesTyped | match | |
| series-string | construct | pandas.Series | pandas.NewSeriesTyped | match | |
| series-bool | construct | pandas.Series | pandas.NewSeriesTyped | match | |
| series-empty | construct | pandas.Series | pandas.NewSeriesTyped | match | |
| series-allnull | construct | pandas.Series | pandas.NewSeriesTyped | match | |
| series-infer-ints | construct | pandas.Series | pandas.NewSeries | match | dtype inference from untyped values |
| series-infer-floats | construct | pandas.Series | pandas.NewSeries | match | |
| series-infer-mixed-numeric | construct | pandas.Series | pandas.NewSeries | mismatch | port takes dtype from first element and truncates 2.5 to 2; pandas promotes to float64 |
| series-infer-mixed-types | construct | pandas.Series | pandas.NewSeries | mismatch | pandas -> object; port coerces to first element's dtype |
| series-infer-strings | construct | pandas.Series | pandas.NewSeries | match | |
| frame-sales | construct | pandas.DataFrame | pandas.NewDataFrame | match | |
| frame-nums | construct | pandas.DataFrame | pandas.NewDataFrame | match | |
| frame-gaps | construct | pandas.DataFrame | pandas.NewDataFrame | match | |
| frame-shape-sales | construct | pandas.DataFrame.shape | pandas.DataFrame.Shape | match | |
| frame-names-sales | construct | pandas.DataFrame.columns | pandas.DataFrame.Names | match | |
| frame-index-sales | construct | pandas.DataFrame.index | pandas.DataFrame.Index | match | |
| frame-dtypes-sales | construct | pandas.DataFrame.dtypes | pandas.Series.DType | match | |
| frame-dtypes-nums | construct | pandas.DataFrame.dtypes | pandas.Series.DType | match | |
| frame-from-map-order | construct | pandas.DataFrame | pandas.FromMap | match | |
| frame-from-map-partial-order | construct | pandas.DataFrame | pandas.FromMap | match | names absent from order are appended sorted |
| astype-float-to-int | construct | pandas.Series.astype | pandas.Series.Astype | match | |
| astype-int-to-float | construct | pandas.Series.astype | pandas.Series.Astype | match | |
| astype-int-to-string | construct | pandas.Series.astype | pandas.Series.Astype | match | |
| astype-string-to-float-bad | construct | pandas.Series.astype | pandas.Series.Astype | mismatch | must fail on both: unparseable text -> float |
| astype-bool-to-int | construct | pandas.Series.astype | pandas.Series.Astype | mismatch | |
| to-csv-whole | csv | pandas.DataFrame.to_csv | pandas.DataFrame.WriteCSV | mismatch | compared as raw text; pandas writes the index by default, so index=False is used to match the port |
| to-csv-fractional | csv | pandas.DataFrame.to_csv | pandas.DataFrame.WriteCSV | match | |
| to-csv-missing | csv | pandas.DataFrame.to_csv | pandas.DataFrame.WriteCSV | mismatch | NA is written as an empty field on both sides |
| to-csv-bool | csv | pandas.DataFrame.to_csv | pandas.DataFrame.WriteCSV | mismatch | pandas writes True/False; the port writes true/false |
| roundtrip-fractional | csv | pandas.read_csv | pandas.ReadCSV | match | |
| roundtrip-whole-floats | csv | pandas.read_csv | pandas.ReadCSV | mismatch | known gap: the port demotes a Float64 column of whole values to Int64 on the way back |
| roundtrip-missing | csv | pandas.read_csv | pandas.ReadCSV | mismatch | |
| roundtrip-bool | csv | pandas.read_csv | pandas.ReadCSV | match | |
| roundtrip-sales | csv | pandas.read_csv | pandas.ReadCSV | mismatch | |
| read-csv-inference | csv | pandas.read_csv | pandas.ReadCSV | match | |
| read-csv-blank-is-na | csv | pandas.read_csv | pandas.ReadCSV | mismatch | |
| read-csv-na-values | csv | pandas.read_csv | pandas.ReadCSVOptions.NAValues | mismatch | |
| read-csv-semicolon | csv | pandas.read_csv | pandas.ReadCSVOptions.Delimiter | match | |
| read-csv-no-header | csv | pandas.read_csv | pandas.ReadCSVOptions.NoHeader | mismatch | pandas names the columns 0,1; the port names them col0,col1 |
| read-csv-quoted | csv | pandas.read_csv | pandas.ReadCSV | match | |
| read-csv-ragged | csv | pandas.read_csv | pandas.ReadCSV | mismatch | pandas silently promotes the extra leading field to the index; the port keeps the first two fields as data. Neither errors. |
| read-csv-mixed-column | csv | pandas.read_csv | pandas.ReadCSV | match | a column that is not uniformly numeric falls back to text |
| gb-groups-count | groupby | pandas.DataFrame.groupby | pandas.GroupBy.Groups | match | |
| gb-groups-two-keys | groupby | pandas.DataFrame.groupby | pandas.GroupBy.Groups | match | |
| gb-sum | groupby | pandas.core.groupby.GroupBy.sum | pandas.GroupBy.Sum | mismatch | |
| gb-mean | groupby | pandas.core.groupby.GroupBy.mean | pandas.GroupBy.Mean | match | |
| gb-min | groupby | pandas.core.groupby.GroupBy.min | pandas.GroupBy.Min | match | |
| gb-max | groupby | pandas.core.groupby.GroupBy.max | pandas.GroupBy.Max | match | |
| gb-count | groupby | pandas.core.groupby.GroupBy.count | pandas.GroupBy.Count | match | count must skip NA on both sides |
| gb-std | groupby | pandas.core.groupby.GroupBy.std | pandas.GroupBy.Std | match | sample std (ddof=1); single-member group must be NA |
| gb-all-aggs | groupby | pandas.core.groupby.DataFrameGroupBy.agg | pandas.GroupBy.Agg | match | the port's complete AggFunc set in one call |
| gb-multi-column-aggs | groupby | pandas.core.groupby.DataFrameGroupBy.agg | pandas.GroupBy.Agg | mismatch | |
| gb-two-keys-mean | groupby | pandas.core.groupby.DataFrameGroupBy.agg | pandas.GroupBy.Agg | match | |
| gb-two-keys-sum-count | groupby | pandas.core.groupby.DataFrameGroupBy.agg | pandas.GroupBy.Agg | match | |
| gb-all-na-group | groupby | pandas.core.groupby.DataFrameGroupBy.agg | pandas.GroupBy.Agg | mismatch | one-row groups where the value is NA |
| gb-bool-agg | groupby | pandas.core.groupby.DataFrameGroupBy.agg | pandas.GroupBy.Agg | mismatch | boolean group key |
| gb-mean-of-string | groupby | pandas.core.groupby.DataFrameGroupBy.agg | pandas.GroupBy.Mean | mismatch | must fail on both: aggregating a non-numeric column with mean |
| gb-std-of-string | groupby | pandas.core.groupby.DataFrameGroupBy.agg | pandas.GroupBy.Std | mismatch | must fail on both: std of a non-numeric column |
| gb-sum-of-string | groupby | pandas.core.groupby.DataFrameGroupBy.agg | pandas.GroupBy.Sum | mismatch | pandas concatenates strings; port yields NA |
| gb-unknown-key | groupby | pandas.DataFrame.groupby | pandas.DataFrame.GroupBy | match | must fail on both: unknown group key |
| gb-unknown-agg-column | groupby | pandas.core.groupby.DataFrameGroupBy.agg | pandas.GroupBy.Sum | match | must fail on both: unknown aggregated column |
| gb-default-naming | groupby | pandas.core.groupby.GroupBy.sum | pandas.GroupBy.Sum | deviation | the port always names the output column <col>_<agg>; pandas keeps the source column name |
| merge-inner | merge | pandas.DataFrame.merge | pandas.DataFrame.Merge | match | |
| merge-left | merge | pandas.DataFrame.merge | pandas.DataFrame.Merge | match | |
| merge-inner-duplicate-right-keys | merge | pandas.DataFrame.merge | pandas.DataFrame.Merge | match | one left row fans out to several right rows |
| merge-left-duplicate-right-keys | merge | pandas.DataFrame.merge | pandas.DataFrame.Merge | match | |
| merge-key-not-first-column | merge | pandas.DataFrame.merge | pandas.DataFrame.Merge | mismatch | output column order when the join key is not the left frame's first column |
| merge-key-not-first-column-left | merge | pandas.DataFrame.merge | pandas.DataFrame.Merge | mismatch | |
| merge-colliding-columns | merge | pandas.DataFrame.merge | pandas.DataFrame.Merge | match | non-key collision: port suffixes _left/_right, pandas _x/_y |
| merge-no-overlap | merge | pandas.DataFrame.merge | pandas.DataFrame.Merge | match | must fail on both: key absent from the right frame |
| merge-bad-key | merge | pandas.DataFrame.merge | pandas.DataFrame.Merge | match | must fail on both: key absent from both frames |
| merge-right-unsupported | merge | pandas.DataFrame.merge | — | mismatch | the port has no right join; expected to fail on the Go side only |
| merge-outer-unsupported | merge | pandas.DataFrame.merge | — | mismatch | the port has no outer join; expected to fail on the Go side only |
| merge-cross-unsupported | merge | pandas.DataFrame.merge | — | mismatch | the port has no cross join; expected to fail on the Go side only |
| dropna-sales | missing | pandas.DataFrame.dropna | pandas.DataFrame.DropNA | match | |
| dropna-gaps | missing | pandas.DataFrame.dropna | pandas.DataFrame.DropNA | match | |
| dropna-nothing-missing | missing | pandas.DataFrame.dropna | pandas.DataFrame.DropNA | match | |
| fillna-one-column-int | missing | pandas.DataFrame.fillna | pandas.DataFrame.FillNA | match | |
| fillna-one-column-float | missing | pandas.DataFrame.fillna | pandas.DataFrame.FillNA | match | |
| fillna-bool-column | missing | pandas.DataFrame.fillna | pandas.DataFrame.FillNA | match | |
| fillna-all-columns-zero | missing | pandas.DataFrame.fillna | pandas.DataFrame.FillNA | match | empty column name fills every column |
| fillna-float-into-int-column | missing | pandas.DataFrame.fillna | pandas.DataFrame.FillNA | mismatch | pandas promotes the column to float; the port coerces the fill value to int64 |
| fillna-unknown-column | missing | pandas.DataFrame.fillna | pandas.DataFrame.FillNA | mismatch | pandas raises; the port silently no-ops |
| isna-mask | missing | pandas.Series.isna | pandas.Series.IsNA | match | |
| series-dropna | missing | pandas.Series.dropna | pandas.Series.DropNA | match | |
| series-fillna | missing | pandas.Series.fillna | pandas.Series.FillNA | match | |
| series-fillna-string | missing | pandas.Series.fillna | pandas.Series.FillNA | match | |
| filter-mask | mutate | pandas.DataFrame.__getitem__ | pandas.DataFrame.Filter | match | |
| filter-mask-none | mutate | pandas.DataFrame.__getitem__ | pandas.DataFrame.Filter | match | |
| filter-mask-all | mutate | pandas.DataFrame.__getitem__ | pandas.DataFrame.Filter | match | |
| filter-mask-wrong-length | mutate | pandas.DataFrame.__getitem__ | pandas.DataFrame.Filter | match | must fail on both: mask length mismatch |
| filter-gt-int | mutate | pandas.DataFrame.__getitem__ | pandas.DataFrame.FilterFunc | match | NA row must be excluded on both sides |
| filter-le-float | mutate | pandas.DataFrame.__getitem__ | pandas.DataFrame.FilterFunc | match | |
| filter-eq-string | mutate | pandas.DataFrame.__getitem__ | pandas.DataFrame.FilterFunc | match | |
| filter-ne-string | mutate | pandas.DataFrame.__getitem__ | pandas.DataFrame.FilterFunc | match | |
| filter-eq-bool | mutate | pandas.DataFrame.__getitem__ | pandas.DataFrame.FilterFunc | match | |
| filter-unknown-column | mutate | pandas.DataFrame.__getitem__ | pandas.DataFrame.FilterFunc | mismatch | must fail on both: unknown column |
| with-column-new-float | mutate | pandas.DataFrame.assign | pandas.DataFrame.WithColumn | match | |
| with-column-replace | mutate | pandas.DataFrame.assign | pandas.DataFrame.WithColumn | match | replacing must keep the original column position |