Skip to content

fix(text): normalize ArrowDtype string and categorical columns - #220

Merged
kevincostner17 merged 1 commit into
mainfrom
fix/text-dtypes
Sep 14, 2026
Merged

kevincostner17 merged 1 commit into
mainfrom
fix/text-dtypes

Conversation

@kevincostner17

Copy link
Copy Markdown
Contributor

Summary

pd.ArrowDtype(pa.string()) columns (pandas ≥ 2) now go through whitespace stripping, sentinel normalization, fix_dtypes and profile issue detection, just like the same data as string[pyarrow].

  • _is_stringlike_dtype also accepts Arrow string, large_string and string_view.
  • Type inference runs on a string[pyarrow] view, because Arrow-backed parse results don't implement the arithmetic the numeric check uses. Without the view, simply marking these columns as text crashes fix_dtypes with NotImplementedError: mod not implemented.

Categorical columns with text categories are now repaired, and they keep the categorical dtype and the ordered flag. This follows the choice made for #212.

  • Values are normalized the same way as the equivalent object column, so the counts match.
  • Categories that become equal merge (for example " a " and "a"), and sentinel categories are removed.
  • fix_dtypes still leaves categoricals alone, and fd.profile reports their whitespace and sentinel issues without suggesting a dtype.

fd.clean_text now picks its default columns with the same text-dtype check. docs/cleaning-engine.md notes which column types are repaired.

Issue repro on this branch

Python 3.12 / pandas 2.3.3 (the Arrow case is pandas ≥ 2 only; categorical output is the same on pandas 1.5.3):

arrow: ['a', <NA>, '3', '4']
string[pyarrow]: ['a', <NA>, '3', '4']
categorical: category ['a', nan, 'b', nan]
object: ['a', nan, 'b', nan]
profile categorical: ['1 value(s) with surrounding whitespace', '2 sentinel value(s) meaning missing']

Tests

  • tests/test_strings.py:
    • Arrow and string[pyarrow] give the same values and actions for text, numeric-looking and date-looking columns.
    • A categorical keeps its dtype and ordered flag, gets merged categories and correct counts, and ends up with the same values as the object column.
  • tests/test_profile.py: profile issues for categorical and Arrow string columns.

Local lane pytest -m "not online and not large" on Python 3.12 (numpy 2.5) and Python 3.9 (pandas 1.5.3) passes, except the five sandbox tests that also fail locally on main (they need an installed package). ruff check . and mypy src/freshdata pass.

Closes #212

Whitespace stripping, sentinel normalization, fix_dtypes and the profile's
text issues skipped two kinds of text column:

- pd.ArrowDtype(pa.string()) (pandas >= 2): _is_stringlike_dtype only knew
  object and StringDtype. It now accepts Arrow string/large_string/string_view.
  Type inference parses through a string[pyarrow] view, because Arrow-backed
  parse results lack arithmetic the numeric check relies on (e.g. `%`), so the
  column cleans exactly like the same data as string[pyarrow].
- Categorical columns: categories with text are repaired too, and the column
  keeps its categorical dtype and `ordered` flag. Values are normalized like
  the equivalent object column (same counts); categories that become equal
  merge and sentinel categories disappear. fix_dtypes still leaves categoricals
  alone, and the profile reports their whitespace/sentinel issues without a
  dtype suggestion.

fd.clean_text's default column selection uses the same text-dtype check.

Closes #212
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: ad980a21-eb5c-4431-8a37-7af9452e437e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

FreshData benchmark report — performance

  • freshdata: ?
  • python: ?
  • platform: ?
fixture n_rows n_cols p50 s p95 s peak MB repair % false-repair % preserve % trust monotonic export %

Authored-code reduction (Metric 6)

@kevincostner17
kevincostner17 merged commit e2e2d18 into main Sep 14, 2026
21 checks passed
@kevincostner17
kevincostner17 deleted the fix/text-dtypes branch September 14, 2026 19:56
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.

pd.ArrowDtype string and categorical columns skip whitespace/sentinel normalization

1 participant