TensorFlow: How to combine rows of tensor with summing the 2nd element of tensor which has the same 1st element?

喜你入骨 提交于 2021-02-08 10:19:43

问题


For example, I want to add the 2nd element of this tensor where the 1st element is same. Any Numpy based solution is also welcomed!

  • From :
x = tf.constant([
    [1., 0.9],
    [2., 0.7],
    [1., 0.7],
    [3., 0.4],
    [4., 0.8]
], dtype=tf.float32)
  • To:
x = tf.constant([
    [1., 1.6],
    [2., 0.7],
    [3., 0.4],
    [4., 0.8]
], dtype=tf.float32)

回答1:


numpy solution:

x = np.array([
    [1., 0.9],
    [2., 0.7],
    [1., 0.7],
    [3., 0.4],
    [4., 0.8]])

ans = np.array([[i,np.sum(x[np.where(x[:,0]==i), 1])] for i in set(x[:,0])])

gives

array([[1. , 1.6],
       [2. , 0.7],
       [3. , 0.4],
       [4. , 0.8]])

you will not be able to do this for a 'tf.constant()', as it is a constant variable and does not support having its values changed. If you want to change values within tensorflow data structures it is best to either pass values to a tf.placeholder or use a tf.Variable. However these require predefined dimensions, and cannot have their sizes changed as desired in your question.




回答2:


Thanks FinleyGibson for the Numpy solution and some useful TensorFlow pointers! This is my solution in TF with using tf.unique_with_counts() and tf.segment_sum():

x = tf.constant([
    [1., 0.9],
    [2., 0.7],
    [1., 0.7],
    [3., 0.4],
    [4., 0.8]
], dtype=tf.float32)

with tf.Session() as sess:
    y, idx, y_counts = tf.unique_with_counts(x[:, 0])
    idx_sorted = tf.sort(idx, axis=-1, direction='ASCENDING')
    score_sum = tf.segment_sum(x[:, 1], idx_sorted)
    result = tf.stack((y, score_sum), axis=1)
    print(sess.run(result))

[[1.       1.5999999]
[2.        0.7      ]
[3.        0.4      ]
[4.        0.8      ]]

EDIT:

  • Seems like the above solution was not properly ordering rows/columns pairs. Here is the fixed version.
with tf.Session() as sess:
    x = tf.constant([
        [2., 0.7],
        [1., 0.1],
        [3., 0.4],
        [4., 0.8],
        [1., 0.9]], dtype=tf.float32)

    def matrix_sort(a, col):
        return tf.gather(a, tf.nn.top_k(-a[:, col], k=a.get_shape()[0].value).indices)

    sorted_x = matrix_sort(matrix_sort(x, 1), 0)
    labels = sorted_x[:, 0]
    scores = sorted_x[:, 1]
    y, idx, y_counts = tf.unique_with_counts(labels)
    score_sum = tf.segment_sum(scores, idx)    
    result = tf.stack((y, score_sum), axis=1) 
    print(sess.run(result))

[[1.  1. ]
 [2.  0.7]
 [3.  0.4]
 [4.  0.8]]



来源:https://stackoverflow.com/questions/57959305/tensorflow-how-to-combine-rows-of-tensor-with-summing-the-2nd-element-of-tensor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!