Python NaN is a special IEEE 754 floating-point value for an undefined numeric result, and it must be tested with math.isnan rather than equality.
NaN is useful because a numeric pipeline can carry an invalid result without immediately crashing. That same property makes it dangerous when the pipeline reaches an API, a database, a dashboard, or a billing calculation without validation.
Table of contents
- Create and identify NaN correctly
- NaN is not None and it is not false
- Know how NaN propagates
- Validate serialization and database boundaries
- Make bad numeric states observable
- How this fits the rest of the stack
- FAQ
Create and identify NaN correctly
Python can create NaN with float('nan') or math.nan. NumPy and pandas expose their own helpers, but ordinary scalar values can be checked with math.isnan. The defining surprise is that NaN is not equal to itself.
import math
value = float('nan')
print(value == value) # False
print(math.isnan(value)) # True
Do not use value == float('nan'). It will be false even when value is NaN. For mixed inputs, validate the type before calling math.isnan, because strings and None are not floating-point values.
NaN is not None and it is not false
None represents absence as an object. NaN is a present floating-point value with unusual comparison rules. It is also truthy, so if value will not reject it. A truthiness guard that catches zero and None can let NaN pass directly into a calculation.
Keep state semantics explicit: missing input, invalid numeric input, and a valid computed zero deserve separate handling. Converting all three to one fallback makes later debugging almost impossible.
Know how NaN propagates
Many arithmetic operations involving NaN return NaN. An invalid sensor value or failed conversion can therefore contaminate aggregates, model features, prices, and metrics several steps later. Aggregation libraries differ: some functions propagate NaN while others skip it by default.
values = [12.0, float('nan'), 8.0]
clean = [v for v in values if not math.isnan(v)]
average = sum(clean) / len(clean)
Choose whether to reject, impute, skip, or preserve invalid values, and record that choice. Quietly dropping NaN may be appropriate for a chart but unacceptable for an invoice.
Validate serialization and database boundaries
Strict JSON has no NaN literal. Some Python serializers emit NaN as a non-standard extension, while strict consumers reject it. Configure strict serialization or sanitize numeric data before returning an API response.
Database behavior depends on the engine and column type. Decide whether an invalid float should remain NaN, become SQL null, or fail validation. Apply the rule at a clear boundary and add tests for it instead of letting driver defaults define product behavior.
Make bad numeric states observable
Count rejected and imputed values, include the source field and pipeline stage in errors, and sample safe identifiers for investigation. Alert on a change in rate rather than every individual NaN. One malformed reading is data; a sudden thousand-fold increase is an incident.
Validate before important calculations and before serialization. Numeric correctness is a production feature, not a cleanup step for whoever owns the dashboard later.
How this fits the rest of the stack
If the pipeline behind those numbers needs a Python service, database, worker, and storage, compare the full deployment in the RunxBuild hosting calculator. Then use the RunxBuild dashboard to ship it with logs close enough to catch the next invalid value.
Useful related references:
- Python Not Equal: != vs is not, and Why the Difference Bites
- Python Integer Division: Why // Floors and Why -7 // 2 Is -4
- Python for Websites: Where It Fits and Where It Does Not
- Python services on RunxBuild
FAQ
How do I create NaN in Python?
Use float('nan') or math.nan. Both produce a floating-point NaN value.
How do I check whether a value is NaN?
For a scalar float, use math.isnan(value). NumPy arrays commonly use numpy.isnan, while pandas offers isna helpers.
Why is NaN not equal to itself?
IEEE 754 defines NaN comparisons so that equality is false, including comparison with another NaN. Use an isnan function instead.
Is NaN truthy in Python?
Yes. bool(float('nan')) is true, so a general truthiness check does not filter NaN.
Can JSON contain NaN?
Standard JSON does not define NaN. Some serializers allow a non-standard token, but strict clients reject it, so validate or convert before serialization.