【问题标题】:Insert elements to tensor according to array of indices using Tensorflow使用 Tensorflow 根据索引数组将元素插入张量
【发布时间】:2021-04-24 01:17:55
【问题描述】:

使用 Tensorflow,我想根据索引数组 (idx) 的值将值插入数组 (X),以便索引表示的每个实体在结果数组中具有相同数量的元素。

例如,假设初始数组X和索引如下

X = tf.range(6) # [0, 1, 2, 3, 4, 5]
idx = tf.constant([0, 0, 1, 1, 1, 2]) 
fill_value = -999 # value to insert

idx 中,值 1 出现的次数最多 (3),因此我想在 X 中填充其他索引值的缺失条目以匹配 3。这意味着插入一个值0,因为它出现了 2 次,并且 idx 值 2 的两次插入。

结果应该是[0, 1, -999, 2, 3, 4, 5, -999, -999]

我已经能够通过使用不规则张量来做到这一点,但是在我的应用程序中,不支持不规则张量。作为参考,我是这样做的:

# solution using ragged arrays
X_ragged = tf.RaggedTensor.from_value_rowids(X, idx)
result = x_ragged.to_tensor(default_value=fill_value)
tf.reshape(result, -1)
# <tf.Tensor: shape=(9,), dtype=int32, numpy=array([ 0, 1, -999, 2, 3, 4, 5, -999, -999], # dtype=int32)>

【问题讨论】:

    标签: tensorflow tensorflow2.0


    【解决方案1】:

    有很多方法可以编码,但如果你从

    elements, index, count = tf.unique_with_counts([0, 0, 0, 0, 1, 1, 2])
    print('Elements ',elements)
    

    它提供了您需要的所有数据,然后以下代码用“填充物”填充“粗糙”张量

    注意:我已经硬编码了if( slice.shape[0] &lt; 4): 这个。这是 最长重复值的长度,但您可以从 tf.unique_with_counts 并通过它。 我也不考虑缺失值 - [0, 0, 0, 0, 2]。但是上面代码中的elements 为您提供了现有的内容。所以你可以 当你找到一个值时,使用一个简单的循环添加一行“填充” 不见了。

    import tensorflow as tf
    
    fill_value = tf.constant([-999]) # value to insert
    elements, index, count = tf.unique_with_counts([0, 0, 0, 0, 1, 1, 2])
    print('Elements ',elements)
    values = [3, 1, 4, 1, 5, 9, 2]
    
    ta = tf.TensorArray(dtype=tf.int32,size=1, dynamic_size=True,clear_after_read=False)
    
    def fill_values(slice,i):
        slices = slice
        if( slice.shape[0] < 4):
            for j in range( 4 - slice.shape[0] ):
                slices = tf.concat([slices,fill_value],0)
                tf.print('Fill ',slices)
        return ta.write(i,slices)
    
    def slices( begin, c, i, filler ):
        slice = tf.slice(  values,
                           begin=[ begin ],
                           size=[ c[i] ])
        begin = begin + c[i]
        tf.print('Slice' , slice)
        ta = fill_values(slice,i) # If I don't use the return value this warning is shown
        print('TensorArray ', ta.stack()) # So I print it
        # Note: The output of this function should be used.
        # If it is not, a warning will be logged or an error may be raised.
        # To mark the output as used, call its .mark_used() method.
        return [begin , c, tf.add(i, 1), filler]
    
    def condition( begin, c, i, _ ):
        return tf.less(i, tf.size(c))
    
    i = tf.constant(0)
    filler = tf.constant(-999)
    r = tf.while_loop(  condition,slices,[0, count, i, filler ])
    print('TensorArray ', ta.stack())
    

    输出是

    TensorArray  tf.Tensor(
    [[   3    1    4    1]
     [   5    9 -999 -999]
     [   2 -999 -999 -999]], shape=(3, 4), dtype=int32)
    

    但是tf.RaggedTensor 更容易。不知道为什么你不能使用它。

    【讨论】:

      猜你喜欢
      • 2019-05-07
      • 2020-12-04
      • 2018-07-04
      • 2019-07-15
      • 2019-06-13
      • 2021-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多