Technology Aug 30, 2026 · 3 min read

The first thing I check before trusting any dataset

Every dataset I've ever received came with a description. Almost none of them matched the data. Not because anyone was lying. The person who wrote the README usually described the dataset as it was supposed to be, or as it was six months ago. The data itself has been quietly drifting since then. S...

DE
DEV Community
by Leo Marsh
The first thing I check before trusting any dataset

Every dataset I've ever received came with a description. Almost none of them matched the data.

Not because anyone was lying. The person who wrote the README usually described the dataset as it was supposed to be, or as it was six months ago. The data itself has been quietly drifting since then.

So before I compute a single mean, I run the same short ritual. It takes five minutes and has saved me from shipping wrong conclusions more times than I can count.

1. Count the nulls, then count the fake nulls

df.isna().sum() is the obvious step. The less obvious one is looking for values that mean null but aren't encoded as null:


python
suspects = ["", " ", "-", "N/A", "NA", "null", "None", "0", "-1", "9999"]
for col in df.select_dtypes("object"):
    hits = df[col].isin(suspects).sum()
    if hits:
        print(f"{col}: {hits} suspicious values")

A column with 0% nulls and 30% dashes is a 30%-null column. The mean you'd compute on it is fiction.

2. Look at the distribution, not the summary

df.describe() tells you the mean is 42. It does not tell you that half the rows are exactly 0 and the other half are around 84. Those are very different datasets with the same summary statistics.

df["value"].value_counts().head(10)
df["value"].plot.hist(bins=50)

The value_counts() call is the underrated one. If a continuous column has a single value appearing thousands of times, that value is almost always a default, a cap, or a placeholder — not a measurement.

3. Check the time column against your assumptions

If there's a timestamp, I always ask three questions:

- What timezone? The README says UTC. Is it? Check whether "daily" events cluster around midnight or around 8am — that tells you more than the docs.
- Is it complete? Group by day and count rows. Gaps and sudden drops usually mean an ingestion failure, not a real-world quiet day.
- Is it monotonic where it should be? created_at should never be later than updated_at. Yet it often is.

daily = df.groupby(df["ts"].dt.date).size()
print(daily.describe())
print(daily[daily < daily.median() * 0.5])  # suspiciously thin days

Why this matters

None of this is sophisticated. That's the point. The expensive mistakes in analysis rarely come from choosing the wrong model — they come from feeding a correct model data that doesn't mean what you think it means.

Five minutes of paranoia up front is much cheaper than explaining to someone why last month's numbers were wrong.

What's your first check when a new dataset lands on your desk? I'd genuinely like to add to this list.
DE
Source

This article was originally published by DEV Community and written by Leo Marsh.

Read original article on DEV Community
Back to Discover

Reading List