Skip to content

fix: match profiler-engine.js NA tokens to pandas' STR_NA_VALUES exactly - #534

Merged
yakew7 merged 1 commit into
yakew7:mainfrom
propcgamer20-png:fix/js-na-tokens-match-pandas
Sep 9, 2026
Merged

fix: match profiler-engine.js NA tokens to pandas' STR_NA_VALUES exactly#534
yakew7 merged 1 commit into
yakew7:mainfrom
propcgamer20-png:fix/js-na-tokens-match-pandas

Conversation

@propcgamer20-png

Copy link
Copy Markdown
Collaborator

Problem

assets/profiler-engine.js's NA_TOKENS / isMissing() disagreed with pandas' actual default na_values (pandas.io.parsers.readers.STR_NA_VALUES), which faircode/loaders.py gets by calling plain pd.read_csv(). Two things were backwards:

  • NA_TOKENS included bare lowercase "na" - pandas does not treat that as missing
  • NA_TOKENS excluded "None" - pandas does treat that as missing

and isMissing() did String(v).trim().toLowerCase() before the lookup, erasing pandas' case-sensitivity ("NA" is missing, "na" is not).

Repro (before)

A status column with 2 literal na rows and 2 literal None rows out of 10:

python:  missing_pct 0.2, groups ['active', 'inactive', 'na']       # "None" missing, "na" kept
js:      missing_pct 0.2, groups ['active', 'None', 'inactive']     # exact opposite

Both report 0.2 for opposite reasons - parity is broken for any dataset using literal "na" or "None" text.

Fix

NA_TOKENS now mirrors STR_NA_VALUES verbatim ('', '#N/A', '#N/A N/A', '#NA', '-1.#IND', '-1.#QNAN', '-NaN', '-nan', '1.#IND', '1.#QNAN', '<NA>', 'N/A', 'NA', 'NULL', 'NaN', 'None', 'n/a', 'nan', 'null') and isMissing() compares case-sensitively (drops .toLowerCase()).

After

python:  missing_pct 0.2, groups ['active', 'inactive', 'na']
js:      missing_pct 0.2, groups ['active', 'inactive', 'na']

Test

test_python_js_na_token_parity_on_literal_na_and_none - asserts byte-identical Python/JS structured output for a column with literal na/None cells, plus that "na" survives as a group and "None" counts as missing.

pytest tests/test_js_parity.py -> 22 passed, 1 failed. The failure (test_python_js_profiler_parity_sniffs_quoted_newlines) is pre-existing on main on this platform and unrelated - the 5 real-audit-dataset parity cases all still pass.

Closes #491

🤖 Generated with Claude Code

@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

@propcgamer20-png is attempting to deploy a commit to the yashkewlani2020-gmailcom's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

@yakew7 @ahmdkaml - new PR touching a path you own, please review.

NA_TOKENS/isMissing() disagreed with pandas' real default na_values on two
counts, both backwards:
  - it included bare lowercase "na", which pandas does NOT treat as missing
  - it excluded "None", which pandas DOES treat as missing
and isMissing() lower-cased the cell before comparing, erasing pandas' own
case-sensitivity ("NA" is missing, "na" is not).

So a categorical column with literal "na"/"None" cells parsed differently
in the two engines, breaking the bit-for-bit parity SPEC.md promises.

NA_TOKENS now mirrors pandas.io.parsers.readers.STR_NA_VALUES verbatim and
the comparison is case-sensitive.

Closes yakew7#491

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@propcgamer20-png
propcgamer20-png force-pushed the fix/js-na-tokens-match-pandas branch from 8a2f3b5 to 0c1ec9f Compare September 9, 2026 15:28
@yakew7
yakew7 merged commit 25e4a6f into yakew7:main Sep 9, 2026
15 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

profiler-engine.js's NA_TOKENS disagrees with pandas' actual default na_values, breaking Python/JS parity on literal "na"/"None" cell values

2 participants