Tensorflow indexing with boolean tensor
Solution 1
Try:
ones = tf.ones_like(x) # create a tensor all ones
mask = tf.greater(x, ones) # boolean tensor, mask[i] = True iff x[i] > 1
slice_y_greater_than_one = tf.boolean_mask(y, mask)
See tf.boolean_mask
EDIT: another (better ?) way to do it:
import tensorflow as tf
x = tf.constant([1, 2, 0, 4])
y = tf.Variable([1, 2, 0, 4])
mask = x > 1
slice_y_greater_than_one = tf.boolean_mask(y, mask)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print (sess.run(slice_y_greater_than_one)) # [2 4]
Solution 2
I would not say it is completely not implemented. How's that for a double negative?
Tensorflow actually supports quite a lot of slicing and dicing, although the syntax may be slightly less pretty. For example, if you want to create a new array which is equal to y
when x>1
but equal to 0 otherwise, you can definitely do that. Check out comparison operators e.g.
masked = tf.greater(x,1)
zeros = tf.zeros_like(x)
new_tensor = tf.where(masked, y, zeros)
If, on the other hand, you want to make a new array which contains only the guys where x>1
you can do that by combining where
with the gather
function. Details for gather
can be found at
https://www.tensorflow.org/versions/master/api_docs/python/array_ops/slicing_and_joining
PS. Of course, x>1
is not differentiable with respect to x
... tf may be great, but it doesn't work magic :).
Solution 3
This is not implemented at this moment, here's GitHub issue tracking the progress  https://github.com/tensorflow/tensorflow/issues/206
Solution 4
Was looking for similar capability to reduce a TensorFlow.js tensor by a defined criteria, but TensorFlow.js does not have the boolean_mask function. After much hair pulling and teeth gnashing, cooked up the following, which essentially sums up the total number of true criteria, and then simply selects the topk values to create the subset tensor.
const a = tf.tensor1d([1, 2, 0, 4]);
const b = a.greater(1).sum().get();
const {values, indices} = tf.topk(a, b);
values.print(); # 4,2
indices.print(); # 3,1
And to create a subset tensor of values less than or equal to 1, it's a matter of using tf.neg on the tensor as there is no bottomk function, and then after obtaining the subset tensor via topk, applying tf.neg again to restore the original values.
Solution 5
tf.boolean_mask
does the job, but on some platforms like Raspberry Pi or OSX, the operation is not supported in Tensorflow wheel distributions (Check this tf.boolean_mask not supported on OSX. So an alternative is to use where
and gather
as @Jackson Loper suggested. For example:
x = tf.Variable([1, 2, 0, 4])
ix = tf.where(x > 1)
y = tf.gather(x, ix)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(y))
Related videos on Youtube
pythonic metaphor
Updated on November 28, 2020Comments

pythonic metaphor over 2 years
In numpy, with two arrays of the same shape,
x
andy
, it is possible to do slices like thisy[x > 1]
. How do you achieve the same result in tensorflow?y[tf.greater(x, 1)]
doesn't work andtf.slice
doesn't support anything like this either. Is there a way to index with a boolean tensor right now or is that currently unsupported?
John Liu over 6 yearsNow you can use tf.boolean_select tensorflow.org/api_docs/python/array_ops/…


Xander Dunn over 6 yearsBut both
select
andwhere
take a boolean mask as an input. How does one take the tensorx
as an input and produce a boolean mask that'sTrue
wherex > 1
? 
Xander Dunn over 6 yearsNow being tracked in: github.com/tensorflow/tensorflow/issues/4639

Xander Dunn over 6 yearsIt looks like I'm looking for the comparison operators: tensorflow.org/versions/r0.11/api_docs/python/…