Merlin1896
Merlin1896

Reputation: 1821

Count number of elements in each dimension in tensorflow

Lets say I have a tensor y with shape (batch_size, n) which contains integers. I am seeking a tensorflow function that creates two new tensors from input y.

The first return value w1 should have shape (batch_size, n) and contain at position b,i, one over the number of times the integer in y[b,i] occurs in y[b]. If y[b,i] is zero, then also w1[b,i]=0. Example:

The second return value w2 should simply contain one over the number of different integers (except for 0) in each batch (or row) of y.

y=np.array([[ 0,  0, 10, 10, 24, 24],  [99,  0,  0, 12, 12, 12]])
w1,w2= get_w(y)
#w1=[[0 , 0 , 0.5, 0.5, 0.5, 0.5],  [1, 0, 0, 0.33333333, 0.33333333, 0.33333333]]
#w2=[0.5,0.5]

So, how can I get tensorflow to do this?

Upvotes: 2

Views: 1327

Answers (1)

Vijay Mariappan
Vijay Mariappan

Reputation: 17191

You can use tf.unique_with_counts:

y = tf.constant([[0,0,10,10,24,24],[99,0,0,12,12,12]], tf.int32)

out_g = []
out_c = []
#for each row
for w in tf.unstack(y,axis=0):
    # out gives unique elements in w 
    # idx gives index to the input w
    # count gives the count of each element of out in w
    out,idx, count = tf.unique_with_counts(w)

    #inverse of total non zero elements in w
    non_zero_count = 1/tf.count_nonzero(out)

    # gather the inverse of non zero unique counts
    g = tf.cast(tf.gather(1/count,idx), tf.float32) * tf.cast(tf.sign(w), tf.float32)
    out_g.append(g)
    out_c.append(non_zero_count)
out_g = tf.stack(out_g)
out_c = tf.stack(out_c)

with tf.Session() as sess:
   print(sess.run(out_g))
   print(sess.run(out_c))

#Output:

#[[0.   0.    0.5   0.5        0.5        0.5       ]
#[1.    0.    0.    0.33333334 0.33333334 0.33333334]]

# [0.5 0.5]

Upvotes: 3

Related Questions