ESala
ESala

Reputation: 7058

TensorFlow - Ignore infinite values when calculating the mean of a tensor

This is probably a basic question, but I can't find a solution:

I need to calculate the mean of a tensor ignoring any non-finite values.

For example mean([2.0, 3.0, inf, 5.0]) should return 3.333 and not inf nor 2.5.

I have tried sess.run(tf.reduce_mean([2.0, 3.0, inf, 5.0])) but it returns inf.

Upvotes: 7

Views: 7484

Answers (3)

Dejvovo
Dejvovo

Reputation: 129

The accepted answer works well for the complete reduction, however, if one wants to use reduce_mean over certain axes only, a more complex approach is required:

def reduce_nanmean(tensor, axis=None):
    mask = tf.math.is_finite(tensor)
    numerator = tf.reduce_sum(tf.where(mask, tensor, tf.zeros_like(tensor)), axis=axis)
    denominator = tf.reduce_sum(tf.cast(mask, dtype=tf.float32), axis=axis)
    return numerator / denominator

To get the numerator, the function replaces non-finite numbers (NaN, Inf) with zeros before summing up the numbers in the tensor. To get the denominator (i.e., the number of finite numbers) it sums-up a boolean mask, which masks out the non-finite numbers.

Upvotes: 1

P-Gn
P-Gn

Reputation: 24661

You could use a combination of is_finite and boolean_mask.

import tensorflow as tf

x = tf.constant([2, 3, float('Inf'), 5])
mymean = tf.reduce_mean(tf.boolean_mask(x, tf.is_finite(x)))

sess = tf.Session()
sess.run(mymean)

Note that is_finite will get rid of NaN values as well.

Upvotes: 12

LucasB
LucasB

Reputation: 3573

The given answer is almost correct. The question asked about ignoring non-finite values, the answer only ignores infinite values. They are not the same thing, specifically about nan.

To actually ignore any non-finite values (including nan), use this slightly simpler line instead:

mymean = tf.reduce_mean(tf.boolean_mask(x, tf.is_finite(x))

Upvotes: 8

Related Questions