TensorFlow
data preprocessing
nan values
input data handling
machine learning

How should I handle input data with nan values in TensorFlow?

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

NaN values in TensorFlow input data should almost never be ignored. If they reach model math unchecked, they can spread through the computation graph and turn losses, gradients, and metrics into NaN as well. The right fix depends on what NaN means in your dataset: missing data to be imputed, invalid rows to be dropped, or masked positions that the model should explicitly ignore.

Why NaN Breaks Training

A single NaN can poison downstream operations.

python
1import tensorflow as tf
2
3x = tf.constant([1.0, float('nan'), 3.0])
4print(tf.reduce_mean(x))

The mean becomes NaN, and the same propagation can happen inside dense layers, normalization, losses, and metrics.

That is why the first rule is simple: decide how to handle missing values before feeding them into the model.

Option 1: Remove Bad Rows

If NaN values are rare and represent unusable examples, filtering rows is the simplest approach.

python
1import numpy as np
2
3x = np.array([[1.0, 2.0], [np.nan, 3.0], [4.0, 5.0]])
4y = np.array([0, 1, 0])
5
6mask = ~np.isnan(x).any(axis=1)
7x_clean = x[mask]
8y_clean = y[mask]
9
10print(x_clean)
11print(y_clean)

This is appropriate when losing a few rows does not distort the dataset.

Option 2: Impute Missing Values

If missing values are common, imputing them is often better than dropping too much data.

python
1import numpy as np
2import tensorflow as tf
3
4x = tf.constant([[1.0, float('nan')], [3.0, 4.0], [5.0, float('nan')]])
5column_means = tf.constant([3.0, 4.0])
6
7x_filled = tf.where(tf.math.is_nan(x), column_means, x)
8print(x_filled)

This example replaces NaN with precomputed column means. The key is that the replacement statistics should usually be computed from training data only, not from the validation or test set.

Option 3: Add an Explicit Missingness Signal

Sometimes missingness itself carries information. In that case, do not only impute. Also add a boolean feature indicating whether the value was originally missing.

python
1import tensorflow as tf
2
3x = tf.constant([[1.0, float('nan')], [3.0, 4.0]])
4missing_mask = tf.cast(tf.math.is_nan(x), tf.float32)
5x_filled = tf.where(tf.math.is_nan(x), tf.zeros_like(x), x)
6combined = tf.concat([x_filled, missing_mask], axis=1)
7print(combined)

This lets the model learn that "filled because missing" is different from an actual zero.

Sequence Models May Need Masking Instead

For some sequence tasks, the right answer is not mean imputation. It is masking padded or invalid positions so the model can skip them. That is a different use case from ordinary tabular missing values.

TensorFlow and Keras support masking layers and mask-aware models, but that strategy only makes sense when the missing positions are structural, such as padded time steps.

Use Checks During Debugging

When the problem might come from the model pipeline rather than the raw input, add numeric checks.

python
1import tensorflow as tf
2
3x = tf.constant([1.0, 2.0, 3.0])
4tf.debugging.check_numerics(x, message='Input contains invalid values')

check_numerics is not a preprocessing solution, but it is useful for failing fast during debugging if NaN values are sneaking in later.

Keep Preprocessing Consistent

Whichever strategy you choose, apply it consistently across training, validation, and inference. A model trained on imputed values but served on raw NaN input will fail in production even if training looked fine.

This is a strong reason to keep the preprocessing logic in one reusable pipeline or inside the model input path.

Common Pitfalls

  • Letting NaN values reach the model and hoping TensorFlow will handle them automatically.
  • Computing imputation statistics on the full dataset instead of training data only.
  • Replacing missing values without considering whether the fact of missingness should also be modeled.
  • Using sequence masking ideas for ordinary tabular missing values where imputation is actually required.
  • Debugging only the raw input while NaN values are really being created later in the computation graph.

Summary

  • 'NaN values should be handled before they flow through model computations.'
  • Drop rows only when missing values are rare and the data loss is acceptable.
  • Imputation is the usual choice for common missing values in numeric features.
  • Sometimes a missingness indicator feature is as important as the filled value itself.
  • Keep the chosen strategy consistent across training and inference.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.