我试图操纵指数和源阵列,使得:
结果[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]]]
使用整数高级索引解决方案:
鉴于:
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]]]
说明:
要使用整数高级索引,关键规则是:
- 我们必须提供由整数索引的索引数组。
- 我们必须提供尽可能多的这些索引阵列,因为有源阵列中的尺寸。
- 这些索引阵列的形状必须是相同的,或者,至少所有这些必须broadcastable于单个最终形状。
如何整数高级索引的工作原理是:
鉴于源阵列具有n
尺寸,并且,我们已经因此供给n
整数索引数组:
- 所有这些索引阵列,如果不在同一均匀的形状,将被广播到在单一均匀的形状。
- 要访问任何元素源数组中,我们显然需要指数的n重。 因此,为了产生从源阵列的结果阵列,我们需要几个n元组,一个n元组的最后的结果阵列的每个元素的位置。 对于结果阵列的每个元件位置,索引的n元组将从广播索引数组中的相应元素位构成。 (记住结果阵列具有完全相同的形状,所广播的索引阵列,如上面已经提到的)。
- 因此, 通过遍历在串联的索引阵列 ,我们得到所有的n元组我们需要生成结果数组,在相同形状的广播索引阵列。
运用这一解释上面的例子:
- 我们的源阵列是
nd_source = np.array(source)
,其为2d。 我们的最终结果形状为(3,2,4)
因此,我们需要提供2
索引数组,并且这些索引阵列必须是在最终结果的形状(3,2,4)
或broadcastable到(3,2,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]]]
我们的第二索引阵列indices
。 虽然这不是一个数组,只是一个列表的列表,numpy的是足够的灵活性,将自动转换成相应的ndarray,当我们把它作为我们发送的索引数组。 请注意,此阵列已经在最终期望的结果的形状(3,2,4)
即使没有任何的广播。
遍历串联这两个索引阵列(一个广播的阵列,而另一个用作是),生成numpy的访问我们的源2D阵列所需要的所有2元组nd_source
,并生成在所述形状的最终结果(3,2,4)
。