Skip to content

profiler.py's date-vs-age detection only samples the first 50 rows, missing dates mixed in later #432

Description

@yakew7

Where: faircode/profiler.py's _looks_like_dates (age-vs-date column detection), interacting with _age_to_numeric.

The gap: _looks_like_dates samples series.dropna().astype(str).head(50) - literally the first 50 rows, not a representative sample despite what "looks like" implies. If a column has clean numeric ages in the first 50 rows and date strings appended later (e.g. a second data source merged in below the original rows), the date-check passes on the sampled head, so the whole column is treated as numeric age - and _age_to_numeric's re.search(r"\d+", ...) then grabs the leading digit run of each date string (e.g. "1985-03-21" -> 1985), banding it straight into "75+".

Repro:

>>> import pandas as pd
>>> from faircode import profile
>>> ages = list(range(20, 80))
>>> dates = ['1985-03-21', '1990-07-14', '2001-11-02'] * 20
>>> df = pd.DataFrame({'age': ages + dates})
>>> for g in profile(df)['dimensions'][0]['groups']: print(g['label'], g['count'])
75+ 65
30-45 15
45-60 15
60-75 15
18-30 10

60 birthdate strings are silently collapsed into the oldest age band, with no flag anywhere.

Why it matters: this is exactly the failure mode _looks_like_dates exists to prevent (see SPEC section 2) - defeated by sampling only the head of the column instead of throughout it. Produces a fabricated elderly-skew from what's actually garbage/mixed-source input.

Suggested fix: sample throughout the column instead of .head(50) - e.g. series.dropna().astype(str).sample(min(200, len(series)), random_state=0), or every Nth row - so a column with dates appended after the initial rows is still correctly detected.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions