Search code examples
pythontensorflowmultidimensional-arraytensortensor-indexing

Slice every item except every nth


In tensorflow it is possible to select every nth item with the slicing notation [::n].

But how to do the opposite? I want to select every item except every nth.

For example:

a = [1, 2, 3, 4, 5, 6, 7, 8]

a[2::3] would result in [3, 6]

Now I would like to have the opposite: [1, 2, 4, 5, 7, 8]

The array above is just an example. A solution should work for bigger matrices of the dimension [batch, width, height, channels] in tensorflow. The selection is only done on the channels. Also my matrix contains real values that are non unique. I will also not be able to reshape it further down than to two dimensions ( [batch, channels] )


Solution

  • One option is to create a boolean index by testing the a range index:

    import numpy as np
    start, step = 2, 3
    a[np.arange(len(a)) % step != start]
    # array([1, 2, 4, 5, 7, 8])
    

    You can achieve this similarly in tensorflow using tf.boolean_mask:

    import tensorflow as tf
    
    a = tf.constant([1, 2, 3, 4, 5, 6, 7, 8])
    
    start, step = 2, 3
    mask = ~tf.equal(tf.range(a.shape[-1]) % step, start)
    
    tf.boolean_mask(a, mask).eval()
    # array([1, 2, 4, 5, 7, 8], dtype=int32)
    

    If a is ND tensor, you can specify the axis with boolean_mask; with 4D tensor [batch, width, height, channels] for instance, to select by the fourth axis, i.e the channels, you can set axis=3:

    mask = ~tf.equal(tf.range(a.shape[-1]) % step, start)
    tf.boolean_mask(a, mask, axis=3)