索引一个三维阵列,2D阵列numpy的(Index a 3D array with 2D array

2019-10-29 10:50发布

我试图操纵指数和源阵列,使得:

结果[i] [j] [k]的源= [I] [指数为[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]]]

Answer 1:

使用整数高级索引解决方案:

鉴于:

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. 这些索引阵列的形状必须是相同的,或者,至少所有这些必须broadcastable于单个最终形状。

如何整数高级索引的工作原理是:

鉴于源阵列具有n尺寸,并且,我们已经因此供给n整数索引数组:

  1. 所有这些索引阵列,如果不在同一均匀的形状,将被广播到在单一均匀的形状。
  2. 要访问任何元素源数组中,我们显然需要指数的n重。 因此,为了产生从源阵列的结果阵列,我们需要几个n元组,一个n元组的最后的结果阵列的每个元素的位置。 对于结果阵列的每个元件位置,索引的n元组将从广播索引数组中的相应元素位构成。 (记住结果阵列具有完全相同的形状,所广播的索引阵列,如上面已经提到的)。
  3. 因此, 通过遍历在串联的索引阵列 ,我们得到所有的n元组我们需要生成结果数组,在相同形状的广播索引阵列。

运用这一解释上面的例子:

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

  3. 因此,我们需要提供2索引数组,并且这些索引阵列必须是在最终结果的形状(3,2,4)或broadcastable到(3,2,4)的形状。

  4. 我们的第一个索引阵列是row_indices = np.arange(source_rows).reshape(-1,1,1)source_rows是行中的源,这是数3在这个例子中)此索引阵列具有形状(3,1,1)并且实际上看起来像[[[0]],[[1]],[[2]]] 这是broadcastable到的最终结果形状(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阵列所需要的所有2元组nd_source ,并生成在所述形状的最终结果(3,2,4)



文章来源: Index a 3D array with 2D array numpy