索引带有2D阵列numpy的3D数组



我正在尝试操纵索引和源数组,以便:

结果[i] [j] [k] = source [i] [indices [i] [j] [k]]

我知道如何使用循环进行此操作,但是我正在使用巨大的阵列,我想使用更多的时间效率。我尝试使用Numpy的高级索引,但我真的不理解。

示例功能:

source = [[0.0  0.1  0.2  0.3]
          [1.0  1.1  1.2  1.3]
          [2.0  2.1  2.2  2.3]]
indices = [[[3 1 0 1]
            [3 0 0 3]]
           [[0 1 0 2]
            [3 2 1 1]]
           [[1 1 0 1]
            [0 1 2 2]]]
# result[i][j][k] = source[i][indices[i][j][k]]
result = [[[0.3  0.1  0.0  0.1]
           [0.3  0.0  0.0  0.3]]
          [[1.0  1.1  1.0  1.2]
           [1.3  1.2  1.1  1.1]]
          [[2.1  2.1  2.0  2.1]
           [2.0  2.1  2.2  2.2]]]

使用整数高级索引:

给定:

source = [[0.0,  0.1,  0.2,  0.3],
          [1.0,  1.1,  1.2,  1.3],
          [2.0,  2.1,  2.2,  2.3]]
indices = [[[3, 1, 0, 1],
           [3, 0, 0, 3]],
          [[0, 1, 0, 2],
          [3, 2, 1, 1]],
          [[1, 1, 0, 1],
          [0, 1, 2, 2]]]

使用以下方式:

import numpy as np
nd_source = np.array(source)
source_rows = len(source)      # == 3, in above example
source_cols = len(source[0])   # == 4, in above example
row_indices = np.arange(source_rows).reshape(-1,1,1)
result = nd_source [row_indices, indices]

结果:

print (result)
[[[0.3 0.1 0.  0.1]
  [0.3 0.  0.  0.3]]
 [[1.  1.1 1.  1.2]
  [1.3 1.2 1.1 1.1]]
 [[2.1 2.1 2.  2.1]
  [2.  2.1 2.2 2.2]]]

说明:

要使用整数高级索引,关键规则是:

  1. 我们必须提供由整数索引组成的索引阵列。
  2. 我们必须提供许多这些索引数组,因为源数组中有尺寸。
  3. 这些索引阵列的形状必须相同,或者,至少所有这些索引阵列都必须在单个最终形状上播放。

整数高级索引的工作方式是:

鉴于源数组具有n维度,因此我们提供了n整数索引数组:

  1. 所有这些索引阵列(如果不是相同的均匀形状)将被广播为单一均匀形状。
  2. 要访问源数组中的任何元素,我们显然需要一个索引。因此,为了从源数组生成结果数组,我们需要几个n个tuples,对于最终结果阵列的每个元素位置一个n核。对于结果数组的每个元素位置,索引的n核心将由广播索引阵列中的相应元素位置构造。(请记住,结果数组的形状与已广播的索引阵列完全相同,如上所述)。
  3. 因此,通过串联中的索引阵列,我们获得了生成结果数组所需的所有n-tuples,其形状与广播的索引阵列相同。

将此说明应用于上述示例:

  1. 我们的源数组是nd_source = np.array(source),是2d。
  2. 我们的最终结果形状是(3,2,4)

  3. 因此,我们需要提供2索引数组,这些索引数组必须处于(3,2,4)的最终结果形状,或可广播到(3,2,4) Shape。

  4. 我们的第一个索引数组是row_indices = np.arange(source_rows).reshape(-1,1,1)。(source_rows是源中的行数,在此示例中为3)该索引数组具有Shape (3,1,1),实际上看起来像[[[0]],[[1]],[[2]]]。这是可以广播到(3,2,4)的最终结果形状,并且广播的数组看起来像[[[0,0,0,0],[0,0,0,0]],[[1,1,1,1],[1,1,1,1]],[[2,2,2,2],[2,2,2,2]]]

  5. 我们的第二个索引数组是indices。尽管这不是一个数组,而只是列表的列表,但是当我们将其作为发送索引阵列时,Numpy足够灵活,可以自动将其转换为相应的NDARRAY。请注意,即使没有任何广播,此数组也已经处于(3,2,4)的最终预期结果形状。

  6. 在串联中遍历这两个索引数组(一个是广播的数组,另一个是一个),numpy生成了访问我们的源2D数组nd_source所需的所有2个tuplace,并生成生成形状(3,2,4)的最终结果。

最新更新