Reputation: 7058
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
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
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
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