我正在尝试操纵索引和源数组,使得:
结果[i] [j] [k] =源[i] [索引[i] [j] [k]]
我知道如何使用for循环来做到这一点,但是我使用的是巨型数组,我想使用更省时的方法。我尝试使用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]]]
答案 0 :(得分:0)
给出:
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]]]
要使用Integer Advanced Indexing,关键规则是:
整数高级索引的工作原理是:
鉴于源数组的尺寸为n
,因此我们提供了n
整数索引数组:
将此说明应用于上面的示例:
nd_source = np.array(source)
,即2d。我们的最终结果形状为(3,2,4)
。
因此,我们需要提供2
索引数组,并且这些索引数组必须为(3,2,4)
的最终结果形状,或者可以广播为(3,2,4)
形状。 / p>
我们的第一个索引数组是row_indices = np.arange(source_rows).reshape(-1,1,1)
。 (source_rows
是源中的行数,在此示例中为3
。此索引数组的形状为(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]]]
。
我们的第二个索引数组是indices
。尽管这不是数组,而只是列表的列表,但是当我们将其作为发送索引数组传递时,numpy足够灵活,可以自动将其转换为相应的ndarray。请注意,即使没有任何广播,该数组也已经达到了(3,2,4)
的最终期望结果形状。
依次遍历这两个索引数组(一个广播数组,另一个按原样),numpy生成访问源2d数组{{1}所需的所有2元组。 },并生成形状为nd_source
的最终结果。