Field note · June 27, 2026

21.8% of salary_max_usd is missing

762 blanks in one column, and the one-line check that decides whether dropping them is free.

1 min read ·Statistics ·quality statistics

salary_max_usd on data-job-postings is null in 762 of 3,500 rows.

21.8% missing is enough to matter and small enough to ignore, which is the dangerous range. Nothing errors. The aggregate returns. The number is wrong by an amount nobody can see.

The question is never "how much is missing" — that is one line and it tells you nothing. It is whether the rows with a blank differ from the rows without one:

python
missing = df["salary_max_usd"].isna()

df.groupby(missing)["seniority"] \
  .value_counts(normalize=True) \
  .unstack(fill_value=0) \
  .round(3)

If the two rows of that table look alike, dropping the blanks costs you sample size and nothing else. If they look different, the missingness is carrying information, and every average computed over the survivors is biased in a direction you can usually name.

Here it is informative, and the direction is knowable: postings that hide a band skew junior and non-US, both of which pay less, so the average over disclosed salaries reads high.

"How much is missing" is a completeness metric. "Who is missing" is the finding. The second question costs one more line of code and is the one worth asking.