How to Handle NULLs in PySpark (Use .isNull(), Not == None)

Filtering for NULL values in PySpark with == None silently returns zero rows - every time, for every row. SQL semantics mean anything == NULL evaluates to NULL, not True. The fix is .isNull(). Here's why it works that way and how to get it right.

Data Engineerpythonsparkpyspark

Why == None always returns nothing

In standard Python, x == None works as you'd expect. In PySpark (and any SQL-based engine including DuckDB's Spark-compatible API), the comparison follows SQL NULL semantics:

NULL == NULL   -> NULL   (not True)
NULL == 'foo'  -> NULL   (not False)

The filter() call drops any row where the condition evaluates to anything other than True - including NULL. So F.col("end_date") == None evaluates to NULL for every row that has a NULL end_date, and those rows are filtered out instead of kept. The result: zero rows, and no error message.

The correct pattern: .isNull() and .isNotNull()

PySpark's Column class has dedicated methods for NULL checks:

from pyspark.sql import SparkSession
import pyspark.sql.functions as F

spark = SparkSession.builder.getOrCreate()

df = spark.read.option("header", True).csv("subscriptions.csv")

# Wrong - always returns 0 rows when end_date can be NULL
# active = df.filter(F.col("end_date") == None)

# Correct - returns rows where end_date IS NULL (active subscriptions)
active = df.filter(F.col("end_date").isNull())

active.show()

To find rows where the column is NOT NULL (expired subscriptions):

expired = df.filter(F.col("end_date").isNotNull())

The same rule applies in SQL expressions

If you write PySpark queries using spark.sql() or .filter() with a SQL string, the same rule applies - use IS NULL, not = NULL:

# SQL string form - also correct
active = df.filter("end_date IS NULL")
expired = df.filter("end_date IS NOT NULL")

WHERE end_date = NULL in SQL is a no-op for the same reason: the comparison returns NULL, so no rows match.

How to spot this bug quickly

The signature of the == None bug is a filter that returns zero rows when you know the column has NULL values. Cross-check with:

# Count NULLs in the column - should be > 0 if the bug is present
df.filter(F.col("end_date").isNull()).count()

If that count is positive but your equality filter returned zero, you've found the cause.

Linter coverage

pyspark-stubs and ruff (with the pandas-vet plugin) flag == None comparisons on DataFrame columns. Adding these to your CI catches the pattern before it reaches production.

Want to try it hands-on? HeyDevJob gives you this exact setup in a live cloud workspace in your browser - edit it, run it, and see it work. Free, nothing to install.

Try it in a workspace →

What you'll practice

FAQ

Why does PySpark filter return 0 rows when I filter for None?

PySpark uses SQL NULL semantics. F.col('x') == None evaluates to NULL for every row where x is NULL - not True. The filter drops any row that doesn't evaluate to True, so all NULL rows vanish. Use F.col('x').isNull() instead.

How do I filter for NULL values in a PySpark DataFrame?

Use .isNull() to keep rows where the column is NULL, and .isNotNull() to keep rows where it is not. In a SQL string filter, use IS NULL and IS NOT NULL. Never use == None or = NULL.

Does this problem also apply to DuckDB or Spark SQL?

Yes - any SQL-based engine (DuckDB, Spark SQL, PostgreSQL, BigQuery) follows the same NULL semantics. = NULL always evaluates to NULL, never True. Use IS NULL in SQL and .isNull() in the DataFrame API.

Keep learning

Make an ETL Pipeline IdempotentData projectSpeed Up a Slow SQL Report QueryData projectMake a CSV Importer Resilient to Bad DataData projectData roadmapStep by step to hiredData interview questionsSTAR answersAll Data projectsProjects hub

Learn it by doing. Open this in a live cloud workspace, make the change yourself, and keep a record of the work you can share.

Open the workspace →