Question
In Python, float('nan') represents NaN (“not a number”). How can I reliably check whether a value is NaN?
value = float('nan')
Short Answer
You will learn why NaN behaves differently from ordinary numbers, how to test for it with math.isnan(), and how to handle NaN safely in conditions, collections, and data-processing code.
Concept
NaN stands for Not a Number. It is a special floating-point value used to represent an undefined or invalid numeric result.
For example, a calculation may produce NaN when it cannot produce a meaningful number. Python can create it directly:
value = float('nan')
The reliable standard-library way to check a floating-point value is NaN is math.isnan():
import math
value = float('nan')
print(math.isnan(value)) # True
NaN matters because it does not follow normal comparison rules. In particular, NaN is not equal to itself. This unusual behavior can cause bugs in validation, filtering, and calculations unless code explicitly detects it.
Mental Model
Think of NaN as a numeric field containing an “unknown measurement” marker rather than an actual number.
A normal number can be compared with another number:
10 == 10 # True
But NaN means “there is no meaningful numeric value here,” so Python refuses to say that two NaN markers are equal—even if they appear to be the same:
nan = float('nan')
nan == nan # False
Use math.isnan() as a dedicated scanner that asks: “Is this value the special unknown-number marker?”
Syntax and Examples
Import the math module and pass a floating-point value to math.isnan().
import math
score = float('nan')
if math.isnan(score):
print('The score is missing or invalid.')
else:
print(f'The score is {score}.')
Output:
The score is missing or invalid.
math.isnan() returns a Boolean:
import math
print(math.isnan(3.14)) # False
print(math.isnan(float('nan'))) # True
A NaN value can also be detected with this property:
value = float('nan')
print(value != value) # True
This works because NaN is the only ordinary Python floating-point value that is not equal to itself. However, prefer math.isnan() because its purpose is clear to readers.
Step by Step Execution
Consider this validation function:
import math
def describe_temperature(temperature):
if math.isnan(temperature):
return 'Temperature is unavailable.'
return f'Temperature: {temperature}°C'
reading = float('nan')
message = describe_temperature(reading)
print(message)
Step by step:
float('nan')creates a NaN floating-point value and stores it inreading.describe_temperature(reading)calls the function with that value.math.isnan(temperature)checks whethertemperatureis NaN.- The check returns
True. - The function immediately returns
'Temperature is unavailable.'. print(message)displays:
Temperature is unavailable.
With a valid value such as 22.5, math.isnan(22.5) returns False, and the second return runs instead.
Real World Use Cases
NaN checks are useful whenever numeric input may be absent, invalid, or produced by a calculation.
- CSV and spreadsheet imports: A blank measurement may become NaN after loading data.
- Sensors and monitoring: A device may send an unavailable reading instead of a valid temperature, speed, or voltage.
- Financial calculations: Missing prices or rates should be identified before totals and averages are calculated.
- Web forms and APIs: Validate numeric data before storing it or using it in a calculation.
- Scientific computing: Filter invalid experimental results before graphing or computing statistics.
For example, skip invalid readings when calculating a total:
import math
readings = [12.5, float('nan'), 18.0]
total = 0
for reading in readings:
if not math.isnan(reading):
total += reading
print(total) # 30.5
Real Codebase Usage
In production code, NaN checks are commonly placed near the boundary where data enters the program or just before important calculations.
Guard clause for validation
A guard clause handles invalid input early, keeping the main logic simple.
import math
def calculate_discount(price, percentage):
if math.isnan(price) or math.isnan(percentage):
raise ValueError('Price and percentage must be valid numbers.')
return price * (percentage / 100)
Filtering a collection
import math
values = [10.0, float('nan'), 15.0, float('nan')]
valid_values = [value for value in values if not math.isnan(value)]
print(valid_values) # [10.0, 15.0]
Replacing missing numeric values
Sometimes an application needs a fallback value rather than removing the record.
import math
def value_or_default(value, default=0.0):
return default if math.isnan(value) else value
print(value_or_default(float('nan'))) # 0.0
Choose a fallback carefully. Replacing NaN with 0 is only correct if zero has the intended business meaning.
Common Mistakes
Comparing NaN with ==
This does not work:
value = float('nan')
print(value == float('nan')) # False
Even a NaN value is not equal to itself. Use math.isnan(value) instead.
import math
print(math.isnan(value)) # True
Checking only against a variable containing NaN
This also fails:
missing = float('nan')
value = float('nan')
if value == missing:
print('Missing')
Use math.isnan(value).
Calling math.isnan() on arbitrary text
math.isnan() expects a numeric value that can be treated as a float. Passing non-numeric text raises TypeError.
import math
# math.isnan('unknown') # TypeError
Validate or convert external input first:
import math
text = '3.5'
value = float(text)
print(math.isnan(value)) # False
Forgetting that NaN affects calculations
One NaN can make a result NaN:
total = 10 + float('nan')
print(total) # nan
Check, filter, or replace NaN before calculations where a valid result is required.
Comparisons
| Check or value | Result with NaN | Use it? | Why |
|---|---|---|---|
value == float('nan') | False | No | NaN is never equal to anything, including NaN. |
value != value | True | Sometimes | It detects NaN, but the intent is less obvious. |
math.isnan(value) | True | Yes | Clear standard-library check for floating-point NaN. |
value is None | False | No | None represents absence of an object, not a numeric NaN. |
None and NaN can both represent missing information, but they are different types of values:
import math
print(None is None) # True
print(math.isnan(float('nan'))) # True
Use None when a value is absent by design. Use NaN when working with floating-point data that contains an invalid or undefined numeric result.
Cheat Sheet
import math
value = float('nan')
math.isnan(value) # True: preferred NaN check
math.isnan(4.2) # False
value != value # True for NaN, but less readable
value == float('nan') # False: never use this to detect NaN
- NaN means “not a number.”
- NaN is a
floatvalue in Python. - NaN is not equal to itself:
nan == nanisFalse. - Use
math.isnan(value)for clear, reliable code. - Check values before calculations if invalid readings must not affect the result.
Noneis different from NaN; test it withvalue is None.
FAQ
How do I check whether a value is NaN in Python?
Import math and use math.isnan(value).
import math
math.isnan(float('nan')) # True
Why does float('nan') == float('nan') return False?
The IEEE floating-point rules define NaN as unequal to every value, including another NaN and itself.
Can I use value != value to detect NaN?
Yes. A NaN value is not equal to itself, so value != value is True. Prefer math.isnan(value) because it communicates the intent clearly.
Is NaN the same as None in Python?
No. NaN is a special floating-point value, while None represents the absence of a value. Check them with math.isnan(value) and value is None, respectively.
What happens if I add NaN to a number?
The result is usually NaN.
5 + float('nan') # nan
Does math.isnan() work with integers?
Yes. It returns False for ordinary integers.
import math
math.isnan(10) # False
What should I do when data may be either None or NaN?
Check None first, then call math.isnan() only for numeric values.
import math
if value is None or math.isnan(value):
print('Missing value')
Mini Project
Description
Create a small sensor-reading cleaner. A sensor list may contain valid temperature readings and NaN values when a measurement was unavailable. The program should separate usable readings from invalid ones and calculate an average only from valid data.
Goal
Build a function that removes NaN readings and returns the average of the remaining temperatures.
Requirements
Create a list containing at least one valid float and one float('nan') value.
Use math.isnan() to identify invalid readings.
Keep valid readings in a separate list.
Return None when no valid readings are available.
Print the valid readings and the calculated average.
Keep learning
Related questions
@staticmethod vs @classmethod in Python Explained
Learn the difference between @staticmethod and @classmethod in Python with clear examples, use cases, mistakes, and a mini project.
Add Rows to a Pandas DataFrame in Python
Learn how to add rows to a Pandas DataFrame, why repeated row appends are slow, and when to use loc, concat, or record lists.
Call a Function by Name in a Python Module
Learn how to call a function by name in a Python module using strings, getattr, and safe patterns for dynamic function dispatch.