Skip to content
Everyone knows 3 min read · Nulls 4 practice problems ↓

fillna / dropna

Fill or drop missing values per column, and why fillna(0) leaves string columns alone.

You will learn

  • How to fill missing values with one value or one value per column
  • Why fillna(0) leaves string columns alone
  • How dropna's how, thresh and subset options decide which rows go
  • When filling is wrong and null should stay null

Read first

Comfortable with these? Read on.

TL;DR df.fillna(value) replaces nulls only in columns whose type matches the value; pass a dict such as {"city": "unknown", "qty": 0} to fill per column. df.dropna() removes rows with any null; subset, how="all" and thresh make it precise. Both also exist as df.na.fill and df.na.drop.

fillna

PySparkSpark SQL
result = leads.fillna({"city": "unknown", "score": 0})
SELECT lead_id, name,
       coalesce(city, 'unknown') AS city,
       coalesce(score, 0)        AS score,
       phone
FROM leads

Switch to PySpark to edit and run this example in your browser.

Each column gets its own default, and columns not in the dict keep their nulls. SQL has no fillna: coalesce(col, default) per column is the equivalent.

The type rule

fillna(0) fills only numeric columns, and fillna("n/a") fills only string columns. Nothing errors when a column is skipped, so leads.fillna(0) leaves city null and it is easy to think everything was filled. A dict makes the intent explicit and avoids the surprise.

dropna

PySparkSpark SQL
result = leads.dropna(thresh=3)
SELECT * FROM leads
WHERE (CASE WHEN lead_id IS NOT NULL THEN 1 ELSE 0 END
     + CASE WHEN name    IS NOT NULL THEN 1 ELSE 0 END
     + CASE WHEN city    IS NOT NULL THEN 1 ELSE 0 END
     + CASE WHEN score   IS NOT NULL THEN 1 ELSE 0 END
     + CASE WHEN phone   IS NOT NULL THEN 1 ELSE 0 END) >= 3

Switch to PySpark to edit and run this example in your browser.

CallKeeps a row whenLeads kept
dropna()No column is null1
dropna(how="all")At least one column is not nullall 5 (lead_id is never null)
dropna(subset=["city"])city is not null1, 4
dropna(thresh=3)At least 3 columns are not null1, 4, 5

thresh overrides how. subset limits which columns are checked, and it combines with both.

When not to fill

A null often carries meaning: "not measured", "not applicable", "not yet known". Filling a missing score with 0 makes avg(score) lower, because avg ignores nulls but not zeros. Fill for display and for columns where a default is truly correct (a missing quantity in a cart is 0); keep nulls in data used for statistics.

Input

score valuesavg
80, null, null, null, 5567.5

Output

score valuesavg
80, 0, 0, 0, 5527.0

avg(score) before and after fillna(0)

Related tools

  • coalesce(a, b, c) fills from other columns, not a constant: see the coalesce lesson.
  • df.na.replace(["N/A", ""], None, subset=["city"]) turns placeholder strings into real nulls first, so fillna and dropna see them.
  • For a forward fill (use the last known value), use last(col, ignorenulls=True) over a window.

Common mistakes

Assuming fillna(0) filled every column

It skips non-numeric columns silently. Use a dict.

Filling before computing averages

avg ignores nulls; zeros pull the average down.

dropna() with no subset on wide tables

One optional column being null removes the whole row. Pass subset with the columns that must exist.

Treating "" and "N/A" as missing

They are values, not nulls. Replace them with null first.

Key takeaways

  • fillna with a dict fills per column; a single value only fills matching types.
  • dropna: subset picks the columns, how="all" or thresh decides how many nulls are too many.
  • Filling changes statistics; keep meaningful nulls.
  • Turn placeholder strings into nulls before cleaning.

Check yourself

3 questions

1. df has a null in a string column city. What does df.fillna(0) do to it?

Show the answer

Leaves it null. A numeric fill value only applies to numeric columns.

2. Which call keeps rows with at least 3 non-null values?

Show the answer

dropna(thresh=3). thresh is the minimum number of non-null values a row needs.

3. Scores are 80, null, 60. What is avg(score) after fillna(0)?

Show the answer

46.67. (80 + 0 + 60) / 3. Without filling, avg ignores the null and gives 70.

Practice it

Interview problems that use fillna / dropna: write the PySpark, run it, and get graded on hidden tests.

Solve: Replace Missing Values →

Keep going

Up next · lesson 13 of 35 · 3 min read
dropDuplicates
Remove duplicate rows or keys, and why "keep the latest row" needs a window instead.

Related lessons

Previous: when / otherwise

Primary sources: DataFrame.fillna · DataFrame.dropna