【问题标题】:Array of indexes for each element alongs the first dimension in a 2D array (numpy., tensorflow)沿二维数组(numpy.,tensorflow)中的第一个维度的每个元素的索引数组
【发布时间】:2019-05-08 04:42:26
【问题描述】:
indexes = np.array([[0,1,3],[1,2,4 ]])
data = np.random.rand(2,5)

现在,我想要一个形状为 (2,3) 的数组,其中

result[0] = data[0,indexes[0]]
result[1] = data[1,indexes[1]]

实现这一目标的正确方法是什么?一种可以推广到更大数组(可能更高维)的 numpy 方法。

请注意与this 等问题的区别,其中索引数组包含元组。这不是我要问的。

编辑

这个问题的更一般的表述是:

  • data.shape == (s0, s1, .., sn)
  • indexes.shape == (s0, s1, ..., sn-1, K)
  • 所以,除了最后一个相等之外,它们都有所有维度

result[i, j, ..., k] = data[i, j,...,k, indexes[i, j, ..., k]]

在哪里

len([i, j, ..., k]) == len(data)-1 == len(indexes) - 1

【问题讨论】:

    标签: python numpy tensorflow indexing


    【解决方案1】:

    这里是 NumPy 和 TensorFlow 解决方案:

    import numpy as np
    import tensorflow as tf
    
    def gather_index_np(data, index):
        data = np.asarray(data)
        index = np.asarray(index)
        # Make open grid of all but last dimension indices
        grid = np.ogrid[tuple(slice(s) for s in index.shape[:-1])]
        # Add extra dimension in grid
        grid = [g[..., np.newaxis] for g in grid]
        # Complete index
        index_full = tuple(grid + [index])
        # Index data to get result
        result = data[index_full]
        return result
    
    def gather_index_tf(data, index):
        data = tf.convert_to_tensor(data)
        index = tf.convert_to_tensor(index)
        index_shape = tf.shape(index)
        d = index.shape.ndims
        # Make grid of all dimension indices
        grid = tf.meshgrid(*(tf.range(index_shape[i]) for i in range(d)), indexing='ij')
        # Complete index
        index_full = tf.stack(grid[:-1] + [index], axis=-1)
        # Index data to get result
        result = tf.gather_nd(data, index_full)
        return result
    

    例子:

    import numpy as np
    import tensorflow as tf
    
    data = np.arange(10).reshape((2, 5))
    index = np.array([[0, 1, 3], [1, 2, 4]])
    print(gather_index_np(data, index))
    # [[0 1 3]
    #  [6 7 9]]
    with tf.Session() as sess:
        print(sess.run(gather_index_tf(data, index)))
    # [[0 1 3]
    #  [6 7 9]]
    

    【讨论】:

      【解决方案2】:

      numpy 具有 take_along_axis,它可以按照您的描述进行操作,而且还可以让您选择轴。

      例子:

      >>> a = np.arange(24).reshape(2,3,4)
      >>> i = np.random.randint(0,4,(2,3,5))
      >>> i
      array([[[3, 3, 0, 1, 3],
              [3, 1, 0, 3, 3],
              [3, 2, 0, 3, 3]],
      
             [[2, 3, 0, 0, 0],
              [1, 1, 3, 1, 2],
              [1, 3, 0, 0, 2]]])
      
      >>> np.take_along_axis(a, i, -1)
      array([[[ 3,  3,  0,  1,  3],
              [ 7,  5,  4,  7,  7],
              [11, 10,  8, 11, 11]],
      
             [[14, 15, 12, 12, 12],
              [17, 17, 19, 17, 18],
              [21, 23, 20, 20, 22]]])
      

      【讨论】:

      • TensorFlow 有一个 NumPy 函数的实验版本tf.experimental.numpy.take_along_axis
      猜你喜欢
      • 2018-12-05
      • 2015-02-01
      • 2012-04-10
      • 2020-02-16
      • 2021-03-03
      • 2022-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多